Gamma error in picture scaling
Best Monitor till now
to view this page
was a standard CRT
Dell
M783c
Introduction
There is an important error in most photography scaling
algorithms. All software tested have the problem: The
Gimp,
Adobe Photoshop, CinePaint, Nip2, ImageMagick, GQview, Eye of Gnome,
Paint and
Krita. Also three
different operating systems were used: Linux, Mac OS X and Windows.
Four
exceptions were reported: the Netpbm
toolkit
for graphic
manipulations, the developping GEGL
toolkit, 32 bit encoded images in Photoshop CS3,
the latest version of Image
Analyzer and the image exporters in Aperture 1.5.6.
Photographs that have been scaled with
these software have been degradated. The
degradation is often faint but probably most pictures contain at least
an array where the degradation is clearly visible. I suppose this
happens since the first versions of these software, maybe 20 years ago.
This
photograph of His
Holiness the Dalai Lama was tuned to exploit the
problem. If you want to give it a try then scale it down 50% using your
best software. (If you cannot download the image to your computer by
right-clicking on it then either make a snapshot of the screen or
download the image in this zipped
file.)
This is what you probably will get once the image is scaled by your
software:
How much did you pay for that software? This is a scaling performed by
a correct software, which evidently shows the same as the start image:
If you would like to see how your browser scales the image click here. To get a smoother image
tuned for
TFT displays click here.
When I showed him the examples below, a friend who is
a photographer told me he noticed that error
since a long time and lots of his colleagues did. They never could word
or understand
it. It made them loose a lot of time an caused much frustration. What
about the digital age preserving the informations? My friend tells me
that professional argentic scalings didn't endure
such errors. Now he uses a scaling routine I wrote for him, in the
waiting that the main graphical software improve.
Technically speaking, the problem is that "the computations are
performed as if the scale of brightnesses was linear while in fact it
is an exponential scale." In mathematical terms: "a gamma of 1.0
is assumed while it is 2.2." Lots of filters, plug-ins and scripts
probably make the same error."
Examples
To compare a wrong and a correct scaling of a
photograph of the Kings
Creek in the Lassen National Park click
here. Look at the window title to know which is the correct
scaling. More
simply: the brightest picture is the correct one.
The error appears clearly when scaling the clerid
beetle picture available on Wikipedia. To compare a wrong 1:4
scaling performed using The Gimp with a correct scaling done using a
C++ routine I wrote, you can click
here. (The picture canvas was reduced from 1600x1067 to 1600x1064 before scaling.)
What about drawings? To see a wrong and a correct scaling of a detail
from "The
Pantomimes" by D.H. Friston you can click
here.
What about scientific imagery? The radar view of the north polar region
of Titan
is one of
the outstanding feats of the Cassini-Huygens
mission. The page www.nasa.gov/mission_pages/cassini/multimedia/pia10008.html
shows this view and gives a link to a full resolution picture. To
compare the image on the page with a correct scaling of the full
resolution picture, click here. For this
picture I compressed the correct scaling to approximately the same file
size as the picture on the NASA web
page.
What about your holliday photographs? Next example was cropped out of
the Extersteine
pano available on Wikipedia. It was scaled 1:4 then scaled back 4:1
as tiles so
you can best compare the original with the scaled pictures. To compare click here. You must step back a few meters
from the screen, just enough to
no
more see the difference between the original picture and the correct
scaling. Then click back and forth between the original and the wrong
scaling. Maybe ask somebody to click for you. (By clicking on the image
you will rotate through the pictures.) If you don't have anybody at
hand
neither a wireless mouse, to get an automatic switch between the
pictures with a delay of 2 seconds, click here,
then click on the picture or on the links above to switch between the
two
comparisons.
A counterexample? This peaceful photograph of Northwestern Afghanistan
scales to almost exactly the same picture whatever the software used: click here.
A sideways hint there is a problem?
I
scaled 1:64 a
Wikipedia picture of a Gibraltar Barbary
macaque. There are two
ways to
scale an image 1:64. Either you scale it directly 1:64 in one step or
you scale it 1:2 six times. The result should be the same... Using my
C++
routine the result indeed is the same. But using ImageMagick... To
compare the scaled pictures click here.
You can use your own software to reduce the photograph 1:64 the two
ways and compare...
Dithering? These two examples from Sam Hovecar show how standard
software mix with the gamma and how the routines written by Sam do it
the right way: example
1, example 2.
Fore-explanation
Almost nobody seems to understand the explanation in next chapter. So I
thought
of this analogy to
introduce the subject:
A military vessel carries 8 types of cannonballs. Each
type has a number, from number 1 to number 8:
Type
|
Description
|
Weight
|
1
|
wooden cannonball for exercices
|
1
|
2
|
wooden with radio emitter
|
1.1
|
3
|
wooden, wound in copper
|
1.5
|
4
|
bare aluminum cannonball
|
2.9
|
5
|
aluminum, wound in copper
|
3.1
|
6
|
hollow iron cannonball
|
3.7
|
7
|
hollow lead cannonball
|
6.2
|
8
|
lead cannonball
|
8
|
By some coincidence, cannonballs of type number 1 have a weight of 1 kilogram. Cannonballs of
type 8 have a weight of 8 kilograms. Why not... But
this does not apply to the other types. Type 5, for example, has a weight of
3.1 kilograms.
It is very important to account for each cannonball leaving the armory.
Especially, it is important to compute the weight of what left the
armory. This is important to keep the ship level!
If one cannonball of type 1 left the armory, together
with three cannonballs of
type 2 and two cannonballs of type 6, what is the weight that left
the armory? You sure will make this computation:
1 x 1 kg + 3 x 1.1 kg + 2 x 3.7 kg = 11.7 kg
One day the ship sank and a military inquiry was conducted. They found
the cause of the wrong estimation of the weight left in the armory.
Simply, the officer responsible for the accounting did this computation:
1 x 1 + 3 x 2 + 2 x 6 = 19 "kg"
Explanation
Consider the following test picture:
It is made of two rows of four gray squares.
Step away from your display to no more see checkers and stripes but
just plain gray squares. Or half close your eyes. If you're using a
calibrated display system, all eight squares display the same gray. (By
"display system"
I mean the whole chain: display software -> operating system ->
graphic driver -> graphic
card -> monitor. If one
element of the
chain fails, you're done, unless another element of the chain can be
tuned to compensate.)
If you are using a common CRT display,
the top three checkered squares may show different from the three
striped bottom ones (especially the second checkered square). In that
case, the striped bottom ones are the
reliable
ones.
If you are using a system that asumes an image gamma of 1.8, like
Apple Macintosh computers, the squares will not display equal because
they were computed for a gamma of 2.2. To get that image for a gamma of
1.8 click here.
If you are using a low cost TFT display, the third
column of two squares may show blueish, with a very different
luminosity from the other
squares and that luminosity also changes tremendously when you move
your head up and down. These are gamma and
color problems partially
own to LCD technology and partially engineered on purpose to increase
the brightness at the behalf of display quality. These gamma
problems can partially be coped with using calibration hardware and/or
software. I used xcalib to get an approximately correct display.
This is the test picture reduced 1:2 by my C++ routine:
The second column of squares was reduced to the correct shade of gray.
The eight squares keep showing the same gray. (For a gamma of 1.8 click here.)
This is the same 1:2 reduction yet performed by a current standard
software:
The second column appears much darker. If it does appear the same gray
as the first and fourth columns, your system is out of calibration
(believe me). It may also be that if you reduce the picture with your
own
software, the first and fourth columns are no more made of black and
white pixels but of shades of gray. One could say that your software
made
an error but for such things it is also a matter of preferences and
choices. (For a gamma of 1.8 click here.)
Why did the second column get darker? The problem lies in the gamma.
Explanation follows.
It is
fair to say that on a common
computer system the shades of gray are numbered from 0 to 255. That
makes 256 shades. Shade 0 is supposed to be pitch black. Shade 255 is
supposed to be the brightest white. All shades of gray are in-between.
Shade 1 is just a little brighter than pitch black. Shade 60 is a dark
gray. Shade 170 is a middle gray. Shade 230 is a light gray. This table
should show those grays:
0
|
####
|
1
|
####
|
60
|
####
|
170
|
####
|
230
|
####
|
255
|
####
|
This picture shows all 256 shades, from 0 up to 255:
255 divided by 2 equals 127. At first thought you would believe that
gray number 127 has half the luminosity of gray number 255 (=white).
That would be a "linear" scale. This could have been but it doesn't.
Actually,
the gray that shows half the luminosity of 255 is gray number
186. This is due to the "exponential" scale being used.
If you are versed in Physics or Electronics, next table shows the
luminosity of some numbers of gray, in a linear
scale and in the exponential scale being used. I made the luminosity
range from 0 to 255 to make things more obvious. Then a white pixel and
the screen has a luminosity of say 255 µW (microwatts). Whatever... but
one thing's for sure: a pixel of gray number 128 has a luminosity
of 55.98 µW:
|
luminosity
scales
|
number
|
linear scale
|
exponential
|
0
|
0.00
|
0.00
|
32
|
32.00
|
2.65
|
64
|
64.00
|
12.18
|
96
|
96.00
|
29.73
|
128
|
128.00
|
55.98
|
160
|
160.00
|
91.46
|
186
|
186.00
|
127.37
|
192
|
192.00
|
136.59
|
224
|
224.00
|
191.73
|
255
|
255.00
|
255.00
|
This is the exact same table but with the luminosity expressed in the
range 0 to 1:
|
luminosity
scales
|
number
|
linear scale
|
exponential
|
0
|
0.0000
|
0.0000
|
32
|
0.1255
|
0.0104
|
64
|
0.2510
|
0.0478
|
96
|
0.3765
|
0.1166
|
128
|
0.5020
|
0.2195
|
160
|
0.6275
|
0.3586
|
186
|
0.7294
|
0.4995
|
192
|
0.7529
|
0.5364
|
224
|
0.8784
|
0.7519
|
255
|
1.0000
|
1.0000
|
Why such oddness? Why use an exponential scale? This clever technical
choice was made to best make
use of the narrow amount of 256 numbers. Should the scale have
been linear, the picture below shows what gray number 1 would have
been. It is shown
surrounded by gray number 0 (=pitch black). If it doesn't show properly
then your display is inaccurate; on a TFT maybe move your head up and
down and on a CRT maybe twiddle with your screen's
brightness and
contrast to clearly show a brighter central square:
That gray number 1 in a linear scale, would already have been a quite
bright dark gray. Thanks
to the exponential scale, 27 shades of gray exist in-between
the pitch black and the dark gray shown above. This picture shows those
27 grays between 0 and 28:
Conversely, in a linear scale the shades close to white would all have
seem the same; bright white. This would have been a waste. By using the
exponential scale, gray number 254 is significantly
dimmer than number 255. The difference is faint yet useful. Next
picture shows six squares with shades 250, 251, 252, 253, 254 and 255.
Shade 250 on the left is perceptively dimmer than shade 255 on the
right. On a linear display system, you would never have been able to
tell the difference between the six shades:
If you are versed in Physics or Mathematics, this is the formula:
Where gamma is 2.2 by default on almost every today computer system
(sRGB standard). Or
should be. Pictures encoded in any format are supposed to have their
numbers of grays meant for 2.2 systems by default. Unless
their file
specifies another gamma, of course. Not all picture formats allow to
specify another gamma. Conversely, some professional computer systems
use a gamma of 1.8. Anyway, whatever the gamma of the system and the
gamma of the picture file, the system is requested to display the
picture
correctly. It must translate the numbers of grays if this is
needed.
A gamma of 1.0 yields a linear scale. By the way, this may be a reason
why some professionals prefer a gamma of 1.8. It's closer to a linear
scale, hence the errors are less important when scaling pictures.
This all to explain that gray number 127 does not imply a luminosity
half that of number 255. Gray number 127 implies that the power of
light emitted by the screen must be 22% of the power of bright white.
Conversely, the number of the gray that asks for 50% power is
186.
Suppose that a square of 2x2
pixels is made of two pitch black pixels and two bright white pixels.
Picture below shows such a square of four pixels magnified 64 times:
What happens if we reduce the picture by 1:2? Those four
pixels shrink to one pixel:
That gray pixel is supposed to have the same brightness as the global
result of the former
four pixels. Those four pixels being two pitch black and two bright
white, the mixture of them yields 50% of the energy of bright
white. That is gray number 186.
The error made in all picture scaling algorithms tested is the mean
value of the numbers is computed, instead of their luminosity. This
yields 127, which shows 22%
light
power, which is a gross error. This error is made also when the picture
size is increased (I didn't verify this). Whatever the brightness of
the pixels being merged
or expanded, the error is made and yields more or less drastic damages.
Some pictures, like fuzzy photographs, are almost not degraded by
this error. Sharp pictures with tiny contrasted details are quite
damaged.
Colors
What about colors? Color pictures are made of three primary colors:
red,
green and blue. Each pixel is usually made of three numbers:
- A number of red, between 0 and 255.
- A number of green, between 0 and 255.
- A number of blue, between 0 and 255.
0 red means no red, 255 red means 100% red. And so on for each primary
color. That way, by mixing quantities of each three primary colors, all
colors that your screen displays are created (only quality screens
really display the full palette).
Those three numbers of primary colors use the exact same exponential
scale
as
explained above for grays. Hence colored checkers or stripes undergo
the same degradation by current scaling software. It's not just a
matter of brightness, like for the grays. If an array of a
picture tends to be made of fine details in one primary color and flat
in
another primary color, the color of the details and the overal color
of the array will change drastically.
The test pictures that follow are best viewed with a CRT display or a
quality TFT. Low-cost or laptop TFT displays will show nonsensical
colors unless you calibrate them an look at them from a perfectly
perpendicular angle.
The picture below shows six
colored squares. The left and the right squares on a same row should
look the same on your display (if you step back or half close your
eyes). At least they should have a quite close color. If you have a TFT
display, move your head up and down and find the position in-between
where the colors match best:
Now this is the result of reducing that picture 1:2 with a correct
algorithm and with a common current software. Guess
which one is the
good one:
(For those three images with a gamma of 1.8 click here, here and here.)
The next test picture is made of 3x3
gray squares. The central column
is made of uniform 50% luminosity gray pixels (gray number 186). The
six
squares on the sides are made of stripes of colors, whose overal result
is meant to show the same 50% luminosity gray. Most probably, on your
screen the six squares will display a faint coloration. The more
accurate your
display system, the less colored the squares appear. If you have a
laptop TFT display like mine, just tilt it or move your head up and
down
to see strong colors. At mid-course the squares should be close to gray
(the colors are
complementary: if you move one direction, the bottom left square gets
yellow, the other direction it shows blue; in-between it is close to
gray):
Reduced 1:2:
(For a gamma of 1.8 click here, here and here.)
I spent two hours tuning the next one but I just love the result. If
you are using a
TFT display and the big test picture shows like the wrongly scaled one
down right, move your head downwards. The better the position of your
head, the more the big test picture should look like a flat gray strip
(like its correctly scaled copy, down left):
Next example performs no scaling rather it converts a color image to a
grayscale image. So to say it displays a color movie on a black and
white TV. The square below is supposed to show evenly gray. Two little
squares in the center are meant to show the same gray as the rest but
they do that by mixing color pixels of green and magenta (
and
). The top
left
square is meant for quality TFT displays while the bottom right one is
for CRT displays. (Move you head up and down if you have a standard TFT
display and the little squares look too bright or too dark.) So, it
looks gray but it is a color picture because it contains strongly
colored pixels:
Let's convert that picture to grayscale. Below is what my software
yields. The two little squares formerly made of colors can be
distinguished if you look closely but the overal result is the whole
picture stayed in the same gray, which is the logical and desirable
outcome:
This is a conversion to grayscale made by a standard current software:
(For a gamma of 1.8 click here, here and here.)
Brightness, contrast and other
filters
At first I thought the brightness and contrast filters too made the
gamma error. Then I learned and realized those filters are quite loose
in essence. What's more their principle dates from a time when their
electronic counterpart in the early television sets played directly
with the gamma curve.
Brightness
In The Gimp the brightness tuning is a simple algorithm that tries to
preserve the picture. It has nothing in common with the brightness
tuning of television sets. It has no physical justification either. It
just is a choice that does
increase the overal brightness and pleases the eye. Its principle is
very simple: say the brightness is increased and gray 0 becomes gray
40. Gray 255 will stay gray 255. All grays in-between will increase a
value in-between 0 and 40. Gray 128 will increase of 20...
In CinePaint the brightness tuning adheres to the system used in
televisions. It adds the same value to the numbers of every shade of
gray. Say 0 becomes 40, then 30 becomes 70, 200 becomes 240... just add
40 to all. That seemed heretic and oversimplified to me but actually
this *is* the way television sets behave, for the same reason of
electronic simplicity. Yet there is a problem for color images.
CinePaint bends the colors to achieve an
illusion of high brightness. Indeed a television set can bring the
brightness to its extreme and maintain the colors. CinePaint, on the
contrary, is limitated by the fact each primary color chanel has a
maximum
of 255. To increase the brightness while one primary chanel already is
at
255, they choose to increase the other chanels. To prevent from there
be a visible transition when one color reaches 255, the trick begins
already before... Again, this simply is a choice, that meets needs.
Improvements in image encoding will allow to avoid such tricks.
A first problem I have with these brightness tunings is they depend
on the gamma being used. They won't give the same result on a picture
with a gamma of 1.8 and a picture with a gamma of 2.2.
A second problem is those algorithms are all different. It is not
sane that the brightness filter in different software behave a quiet
different way.
The brightness filter in The Gimp has the disadvantage to be
unreversible by itself. You cannot reverse the effect of an increase in
brightness by
a decrease.
I have no direct objections against those filters. Simply I believe
they should each get a distinctive name. The way they operate should be
explained clearly. For example almost nobody knows what their parameter
means. And they should be available altogether on every
software, with their proper names.
A more "absolute" set of brightness and contrast filters should
be formulated, independent from the gamma and with simple and
meaningfull physical interpretations. I wrote two different
"brightness" filters that have these particularities and have some
advantages when used. For example they better reveal details in
photographs.
The way images are encoded must also be changed, to allow more liberty
and security when using filters. For example I converted a photograph
to 32-bit float encoding in CinePaint, then put it to maximum
brightness, then reversed again to normal brightness. The picture was
deeply damaged. This is logical but insane. In a simply adequate
high-precision
encoding, I should have returned to the exact same image.
Contrast
In CinePaint, the contrast filter does follow the principle of the
television set contrast. But just the principle. A big difference is a
television set multiplies the signal starting from the black point. Say
you double the contrast, then gray number 0 stays 0, 1 becomes 2, 7
becomes 14 and so on. CinePaint applies the same multiplication but
using gray number 127 as a hallucinatory black point. So, 127 stays
127,
128 becomes 129, 134 becomes 141... and 126 becomes 125, 120 becomes
113. This is a choice that makes sense for digital photography. Except
for the fact the "black point number" should have been configurable by
the user.
And please explain to me why I had to type a contrast factor of 0.5 to
get a multiplication of about 2. This all was observed using a
grayscale picture, I don't know yet how colors are handled.
Gamma and Exposure
In CinePaint, the gamma filter is correct (tested on a grayscale
image). I was just puzzled by the
fact it actually computes the inverse of the gamma you type in... To
apply a gamma of 2.2 I had to type 0.4545... But the exposure filter,
available in the same dialog window, makes the error. The principle of
the exposure filter is "what if the photographer had exposed the camera
sensor say two times longer?" You get a brighter picture... In
CinePaint, gray number 0 stays 0, gray number 64 becomes 128 and gray
number 128 becomes 255.
As if it was a linear scale... Wrong... Yet... this is the exact
implementation of a television set contrast filter! Everything
is mixed up... And by the way, why do I have to type an exposure filter
parameter of 1 to get an exposure (wrongly) multiplied by 2?
Others
Numerous other filters sure make the error too.
Other kinds of software and output
systems
Vector drawing software like OpenOffice Draw and Inkscape propose a
"50%" gray. You guessed correctly: it's gray number 127 (128 actually).
In this case the problem is less important. The shades are displayed
and you choose the one that suits your feelings. Anyway I bet the
developers thought that 50% gray has 50% luminosity. Bitmap scaling and
gradient algorithms used by these software surely make the gamma error
too.
While printing this page on a B&W laser printer I got this for the
first test picture. I'l try to make a more reliable photo or scan,
anyway it's obvious there are serious problems. I think the gamma was
computed correctly. The problems arise from a fact symmetrical to the
problem caused by CRT displays. On a CRT, white pixels will bleed
laterally. On this sheet of paper, the black laser printer ink dots
bleeded in all directions. That's why the finely checkered square got
very dark (symmetrically, it gets very bright on a CRT). Anyway this
should have been compensated in the printer driver (just like the
electronics
of CRT displays should do, by the way):
A friend told me the PhotoPrint software makes error with the gamma. It
doesn't print the test images of this text correctly.
Consequences
I tried to see how big Web sites handle their pictures. On Wikipedia,
for example, an image is nearly always available in its original size
and as a thumbnail. Obviously the scaling is done using the wrong
algorithm...
I tried to verify how museums scale the pictures shown on their web
sites. One Guggenheim museum uses an algorithm that confers a kind of
"plastic" look to the scaled pictures. The pictures are encoded in high
quality but since they are transformed to get that "nice" plastic look
I
cannot compare. The Musée du Louvre uses a standard scaling algorithm,
which makes the error. But the pictures are encoded in low quality
JPEG, which makes even more damage than the gamma error. A friend who
is in the business laughed at me and reminded me that museums simply
don't care
to provide correct reproductions. Only some specialized enterprises
make an activity of using high technology to manufacture reliable
reproductions.
I tried to do the
same on the NASA sites. Actually I could not compare the pictures
correctly because the thumbnails inside the text pages seem
to be made using very
coarse graphical tools. The errors are much more important than
the one I'm studying. Now then, those thumbnails don't pretend to
have any scientific exactness and they are correct representations of
what
they link to. So I went testing the big scientific images that the NASA
makes available to the public through its servers. Most often the
pictures are available in two or more scales. All scaled versions I
tested had the problem... Those scaled pictures were never meant to be
used in accurate scientific studies and for lots of them the
degradation is hardly visible. Besides, the original big picture is
always proposed and it is also available in high quality TIFF format...
If you need quality, you get it. Anyway I felt a little bit sorry. Can
we be sure the scientific work that lead to the original pictures was
done correctly?
What about your pictures? Did you store your family photographs in
their original files or did you scale them, did you tune something and
threw the original away? How many amateur astronomers rely on
inaccurate software to handle their photographs?
Solutions
The solution is to make software compute on images expressed in
a linear scale. This implies an increase in the bits per pixel
precision or the use of a comfortable floating point precision.
(If you are using Linux, FreeBSD or other such systems and you wish to
use the software mentioned below, do not follow the install
instructions provided on the web pages of those respective software.
Those procedures are for experts. Far out most probable is that either
the software is already installed on your system or you just have to
tick the software in a list using the appropriate tool on your system
and let it download and install the software automatically. It's very
easy and quite reliable. Worst case is you first have to configure the
appropriate software "repository", so your system gets aware of where
it can find and download the software.)
Aperture
It seems Aperture from
Apple does the job correctly, at least the latest version 1.5.6. I
don't know anything about pevious versions. The previews are computed
wrongly though but this is a minor issue in most cases.
Image Analyzer
The latest version of Image
Analyzer handles the image gamma correctly in some of the common
functions: scaling, rotation, smoothing, inverting and grayscale
conversion.
The gamma can be set by the user but default is 2.2.
Netpbm
For a correct command line scaling algorithm, use pamscale from the
Netpbm toolkit. Note
pamscale will not scale correctly when using the -filter option.
Photoshop
It seems Photoshop CS3 operates on the images properly if they are
expressed in 32 bit format. So you just have to convert an image to 32
bit before making operations like scaling on it. It is not known wether
other versions than CS3 operate correctly in 32 bit format. When the
image is expressed in 8 bit, version CS3 operates wrongly. It is not
either known wether Photoshop CS3 expresses 32 bit images in linear
format or the scaling routine performs the necessary gamma conversions
when scaling 32 bit images.
One drawback is some tools are not yet available for 32 bit encoded
images, like bicubic resampling. Next procedure is more complicated but
it should allow to work around. The only downside would be some
rounding errors (probably not visible) as a result of converting to a
linear gamma and back again:
- Convert to 16 bit/channel mode to minimize rounding errors
(optional).
- Go to "Convert to profile" (in CS3, this is under the Edit menu).
- Select the current profile for the destination space (so that
both the source and destination space are referencing the same color
space) *but do not hit OK*. If your document is not yet color managed,
sRGB is probably the safest guess. This will pre-populate most of the
fields for the next step...
- Select "Custom RGB" for the destination space. You will get a
pop-up window asking for the parameters for your custom color space.
- In the options for setting up a custom color space, leave
everything unchanged except set the gamma to 1.0.
- Press OK in the Custom RGB dialog box and then press OK on the
Convert to Profile dialog box.
- Resize as normal.
- Convert to your previous color space.
- If you converted to 16bit/channel mode, you may want to convert
back to 8bit/channel at this point.
GEGL
It seems GEGL handles images in 32 bit
linear format, which is the ideal solution. It is not yet readily
available to end users.
Cinepaint
Using CinePaint and similar
power software, a workaround is this:
- Increase the image to a higher precision. 32-bit IEEE float is
best but maybe a nuke to annoy a mosquito. (Image -> 32-bit IEEE)
- Convert the image to a linear scale using the gamma tool. (Image
-> Colors -> Gamma-Expose and type 0.454545 as gamma parameter)
(1 / 2.2 = 0.454545...)
- Apply to the image the filters and operations you intent.
- Convert the image back to an sRGB scale. (Image -> Colors
-> Gamma-Expose and type 2.2 as gamma parameter)
The problem is you work on the image without seeing its real colors and
tints of gray. I believe current versions of CinePaint are technically
able to display the image properly while it is expressed in a linear
scale, by loading an appropriate "icc profile"...
ImageMagick
The ImageMagick library
allows to convert images to 16bit format and to
change the gamma. This command performs the whole chain of operations
to resize an image named in.png to an image named out.png. The image is
scaled down to 50%:
convert in.png
-depth 16 -gamma 0.454545 -scale 50% -gamma 2.2 -depth 8 out.png
You can replace the "-scale 50%" with another operation on the image
that you want to be performed correctly.
If you want to work on an image say test.jpg and respect the
gamma, ImageMagick can help you in this way:
- Convert the image to 16 bit format and linear scale with this
command. It produces an image named temp1.ppm. The PPM format is used
because it allows 16 bits per color channel:
convert test.jpg
-depth 16 -gamma 0.454545 temp1.ppm
- Edit this image temp1.ppm with a software that can operate on 16
bit images, like CinePaint. Possibly combine it with other images you
converted the same way to 16 bits and linear scale. One such software
you can use is the command "convert" itself, of course. It has many
possibilities. See its documentation.
- Save the temporary results of your work in files named say
temp2.ppm, temp3.ppm... Still being in 16 bits and linear encoding of
course.
- Once you have the final image, named say temp7.ppm, and you want
to convert it to a compressed and standard format to send it away, use
this command:
convert temp7.ppm
-gamma 2.2 result.png
In the example above I converted back to PNG format because it is a
reliable compressed format. If you wish to convert to JPEG you should
better
specify the quality you desire. A quality of 85 is just fine in most
cases. A quality of 65 is realy poor. If you need the image to be
nearly exact then you must use a quality factor of 95 or maybe 100:
convert temp2.ppm
-gamma 2.2 -quality 85 result.jpg
If you are working on images with contrasted pixels, like
images with digital inserts, or if you wish a very precise encoding,
then to encode properly in JPEG you should forbid the usage of
sub-sampling, like this:
convert temp2.ppm
-gamma 2.2 -quality 95 -sampling-factor 1x1 result.jpg
Should you convert back to a format that allows 16 bit encoding but you
wish a standard 8 bit encoding, then you must ask for it:
convert temp2.ppm
-gamma 2.2 -depth 8 result.ppm
Gimp-gluas
Gimp-gluas is a
plugin for Gimp that allows to run
a Lua script on an
image. Once you installed the plugin, it will be available in the menu
Filters -> Generics -> gluas...
I wrote this script, which you can cut & paste in the Gluas script
edit dialog from Gimp:
-- Image scaling with correct gamma
tile_x = 2
tile_y = 2
gamma = 2.2
tile_surface = tile_x * tile_y
gamma_invert = 1 / gamma
for y = 0, math.floor (height / tile_y) - 1 do
for x = 0, math.floor (width / tile_x) - 1 do
sum_r, sum_g, sum_b = 0, 0, 0
for ly = 0, tile_y - 1 do
for lx = 0, tile_x - 1 do
r, g, b = get_rgb (x * tile_x + lx, y * tile_y + ly)
real_r = r ^ gamma
real_g = g ^ gamma
real_b = b ^ gamma
sum_r = sum_r + real_r
sum_g = sum_g + real_g
sum_b = sum_b + real_b
end
end
real_r = sum_r / tile_surface
real_g = sum_g / tile_surface
real_b = sum_b / tile_surface
r = real_r ^ gamma_invert
g = real_g ^ gamma_invert
b = real_b ^ gamma_invert
set_rgb (x, y, r, g, b)
end
progress (y * tile_y / height)
end
A tile_x of 2 means the image will be halved horizontally. A tile_y of
2 means the image will be halved vertically. This is a rudimentary
scaling algorithm. It just compresses plain tiles of pixels. If pixels
on the right and lower borders cannot fit in full sized tiles they are
dropped.
Another drawback with this script is that it does not resize the image
canvas. You have to crop out the scaled image by yourself.
The main and philosophical drawback is the pixel values are converted
to the linear scale just for the scaling computation, then they are
immediately converted back to the exponential scale. In a proper system
the values should stay in linear scale all the way long till the final
encoding in a compressed file format.
One would wish that such a script would just convert the image to the
linear scale. Then the image would be edited in Gimp using the regular
tools. At the end a symmetric script would convert the image back to an
exponential scale. This is a bad idea because Gimp uses 8 bit values
for each color channel. Dark shades would be exploded.
Every software
Sure you'd like your own favorite graphic software upgrade as soon as
possible to a correct usage of the gamma. For this best is you
communicate with their developers and manufacturers. Write them a mail
or a letter. Explain the problem to your friends and colleagues so they
too may send a demand.
Acknowledgments
I wish to thank for their help, support and advice Dimitri Gathy,
Vincent
Minder and Frédéric Cloth.
Many thanks to Frank Peters for revealing the Netpbm toolkit to me.
Thanks to Sam Hocevar for the dithering examples.
Thanks to Øyvind Kolås for pointing to the GEGL
software.
Thanks to Dustin Harman for seeing the digg.org typo.
Thanks to David Greenspan for pointing to the need to add images
calibrated for Macintosh computers.
Thanks to Jerrad Pierce for the better English wording.
Thanks to Chris King for the chained ImageMagick command.
Thanks to Rylee Isitt for the procedure and details about Photoshop CS3.
Thanks to Derek Hofmann for suggesting to show the image scaled by the
browser.
Thanks to Michael Vinther for reporting Image Analyzer.
Thanks to Simon Lundberg for reporting Aperture 1.5.6.
All product names mentioned are registered trademarks of their
respective owners.