Project Page



Picture of a bee

Jpeg2BW is a program using the well known JPEG library from the Independant JPEG Group and intended to convert JPEG color pictures to high-precision grayscale pictures. What makes the Jpeg2BW different from other projects is that it performs the whole computation in double precision rather than by rounding each value to some 8-bit integer at each step. The converted black & white pictures are finally encoded to a 16bpp grayscale bitmap file, with about 10 acurate bits for each pixel rather than 8 with current methods (read the following article about this issue). Thus the pictures produced by Jpeg2BW should give about 1,000 significant levels of gray (rather than 256).

Reading the JPEG file

There is not much to say about this step; I use the libjpeg which does the job; the single thing to say is that the JDCT_FLOAT method is used for the discrete cosine transform. Here is what tells the manual for the djpeg tool concerning this method:

Use floating-point DCT method. The float method is very slightly more accurate than the int method, but is much slower unless your machine has very fast floating-point hardware. Also note that results of the floating-point method may vary slightly across machines, while the integer methods should give the same results everywhere. rate than the other two.

Converting to RGB colorspace

I don't use the libjpeg for converting the picture to the RGB colorspace. The library is asked to leave the picture in its initial YCbCr format with 8-bits for each channel. When the library converts the picture to the RGB colorspace, values are rounded to the closest integer, which I want to avoid. Don't think you can win some new information with this method, but you can work with more accurate values. Here is one fact: almost each color in a 24bpp YCbCr colorspace could have been one of four or five different colors in some previous 24bpp RGB colorspace. Again, don't think you can find which one to choose (unless by using very clever interpolation methods, but if you care about that you should rather consider using another format than JPEG for your pictures). What I actually say is that rather than rounding the values in the RGB colorspace, I try to remain as close as possible of the information taken in the file. While thinking about these topics, I performed a computation that may have some interest to you:

When converting the 16,777,216 different colors from a 24bpp RGB colorspace into equivalent colors in a 24bpp YCbCr colorspace (what happens when enconding the JPEG picture), only 4,007,339 different colors are reached in the new colorspace. Among which only 22,672 colors are reached from a single RGB color. 34,812 colors are reached from two different colors. 22,024 colors are reached from 3 different colors. 3,020,307 colors are reached from 4 different colors. 907,524 colors are reached from 5 different colors.

Computing in double precision

Once the picture has been uncompressed and converted into the RGB colorspace, all values are computed in double precision, as previously told. You may think that differences will not be very great, but have a look below at both pictures, which show the S channel in the HSL colorspace, as computed with Jpeg2BW (first) and Gimp (second).

saturation exemple (jpeg2bw) saturation exemple (Gimp)

The program

The tool is written in C; it uses two libraries: the libjpeg and guile; you should be able to compile them on several systems. They have been tried on various Unix systems and compiled with commands like: gcc -o jpeg2bw jpeg2bw.c -ljpeg -lguile -lm

Download the source code

Applying a curve to the mask

The program works by merging two different black and white layers with a mask (made from a saturation layer). The various images may be selected with options from the command line. Another feature is important: a curve can be applied to the mask. Follow this link for more informations concerning that point.


I would be very happy to get your comments; please contact me from this contact page.

Valid CSS