JPEGs and color matching

This is driving me nuts.

I’m redoing my webpage. As the background color I’m using a dark blue–#000033 to be specific. It’s one of the Web safe colors. Now, my logos and line art type stuff are all saved as GIFs, as the should be. I have no problems with the logos matching the backgroun color of my web page.

However, as this is a photo site, there is plenty of imagery which requires JPEG compression. The same blue background renders as #000034 when saved.

So I did a test. Created a block. Filled it with #000033. Saved it as a JPEG. Opened it up. Turned into #000034. Saved it at Highest Quality (12). Still came out as #000034. Saved it as a GIF. Came out correctly, at #000033.

Obviously something in the compression is rounding off the values. What’s going on here? Is there no way to color match my JPEG to the background? Does this mean I have to change the BGCOLOR to #000034 and redo my logos with the modified color? It’s a bit of extra work to change all this GIFs, but if I must, I must.

This is really driving me mad.

Did you try using 000032 to see if that rendered to 000033?

I did a test on #000032 and it saved correctly. Strange that #000032 and #000034 work fine but #000033 does not. To be honest, I would say don’t worry. I made a test picture in Photoshop and laid the 3 colors next to each other. No discernable difference.

JPEG consists of several different steps. The part that actually makes it a lossy compression algorithm is called “quantizing”, and basically means that the pixel values are divided by a given value on the compression side, and then multiplied by the same value again at the decompression end. This means that the numbers get smaller, and therefore take up less storage space. The price you pay for this, however, is that the output image will be only an approximation of the input image. In your case, the quantizing-and-dequantizing step apparently leads to a round-off error on that particular colour.

Most image editing software lets you tune the compression level with one or more parameters; have you tried playing with those to see if you can find a setting which happens to produce the correct result?

However, that’s just a trick. When using lossy JPEG, there is NEVER a guarantee that any particular pixel value will survive the compression intact. In fact, in practice you can’t even guarantee that the output will be exactly the same for every decompressor, even for the same input image! For all you know, switching to a different browser or browser version may change things so that #000033 will be represented correctly, but #000034 will not. And as soon as your picture contains anything other than background colour, you will notice that, near the edges of foreground objects, pixels which should all be in the background colour actually have slightly different colours!

In short, if you need perfectly matching colours, you can’t use a lossy compression algorithm, sorry.

(Actually, the above is simplified to the point of not being true at all. What gets quantized are not the raw pixel values, but the output of a two-dimensional Discrete Cosine Transform which converts the pixes from the spatial domain to the frequency domain. Because high-frequency components are usually less important to the human eye, they can be quantized more aggressively. Unfortunately, high frequencies are important for encoding discontinuities, which is why you get those ugly wavy lines around sharp edges when choosing a high compression ratio.)

Hidden trick. Do not use the HTML background color of the web page. Instead, create a jpg of the color you want for your web page and use that as your page’s background color. I’ve found more often than not a brower’s engine will render an HTML background color just a wee bit differently than if I had used a background image of the same color.

I was thinking that might be a solution. I remember years ago coming across a web page and saw a one-pixel gif tiled all across the screen as a background and wondering “What kind of idiot does this?” And now I know.