Gamma error in picture scaling


Introduction
Examples
Fore-explanation
Explanation
Colors
Other kinds of software and output systems
Brightness, contrast and other filters
Consequences
Solutions
Acknowledgments

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.)

The Dalai Lama

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:
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:
  1. Convert to 16 bit/channel mode to minimize rounding errors (optional).
  2. Go to "Convert to profile" (in CS3, this is under the Edit menu).
  3. 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...
  4. Select "Custom RGB" for the destination space. You will get a pop-up window asking for the parameters for your custom color space.
  5. In the options for setting up a custom color space, leave everything unchanged except set the gamma to 1.0.
  6. Press OK in the Custom RGB dialog box and then press OK on the Convert to Profile dialog box.
  7. Resize as normal.
  8. Convert to your previous color space.
  9. 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:
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 test.jpg -depth 16 -gamma 0.454545 temp1.ppm
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.



Eric Brasseur  -  August 30 2007  till  March 31 2008       [ Homepage | eric.brasseur@gmail.com ]