revised 02/16/2008
This section discusses color images and the PPM color image file format.
The retina of the human eye contains three types of receptor cells for color perception. These cells are the red, green, and blue cone cells. When all three cone cells in a region of the retina are equally stimulated a perception of white is produced. When the three types of cells are stimulated in different amounts, color is perceived. For example, if the red cone cells are stimulated more than the others, the color is perceived as a shade of red. If yellow light falls on a patch of the retina, the red and green cone cells are equally stimulated and the perceived color is yellow. However, if equal amounts of red and green light fall on a patch of the retina, the perceived color is also yellow, even if no yellow light is actually present.
Various mixes of red light, green light, and blue light result in a wide range of perceived colors. This means that computer monitors do not need to actually produce a wide range of colors; all they need to produce is various mixes of just three colors: red, green, and blue.
Usually color mixes are described in Red, Green, Blue order. This is the same order as the spectral colors. Often these three values are called a color triple and shown inside parentheses, like (R, G, B). Sometimes the three values are called called RGB values.
So digital color images only need to specify an amount of
red, green, and blue for each pixel of the image.
Here is a color
image, kernighan.jpg
,
followed by images that show the amount of red, green, and blue
present in each pixel.
Full Color Image | Red Values | Green Values | Blue Values |
Think of a color image as a 2D array of little squares, just like a gray level image. As with gray level images, each little square is filled with three values: one for red, one for green, and one for blue. Each little square is called a pixel, and a pixel contains a triplet of values. Here is an enlargement of a section of the Kernighan image that shows the individual pixels, each filled with a three color values.
Full Color Image | Red Values | Green Values | Blue Values |
Another way to think of this is that a color image consists of three separate images: a red image, a green image, and a blue image. Displaying these images simultaneously creates the perception of many colors. Sometimes one of these images is called a channel, so a color image is said to have a red channel, a green channel, and a blue channel. Whether a color image consists of pixels with RGB values, or consists of three color channels is conceptual. The PPM image file format is organized with the three-colors-per pixel idea. Some image processing operations are easier to visualize in terms of color channels.
Every perceived color that you see on a monitor is the result of mixing red, green, and blue light. On a computer monitor, the intensity of each of these lights can be set to a minimum value up to a maximum value. For us, the minimum value will be designated zero and the maximum value will be designated 255. The inside screen of a cathode ray tube monitor is painted with spots of chemicals that glow red, green, or blue when hit by a beam of electrons. How much red, green, and blue light is emitted from a small patch on the screen of such a monitor is controlled by how many electrons hit the patches of chemicals.
Here are the three lights that your monitor produces for red, green, and blue. These three images (ideally) each turn on just one color on your monitor, corresponding to (R, G, B) color triplets of (255, 0, 0), (0, 255, 0), and (0, 0, 255).
Red Only (255, 0, 0) |
Green Only (0, 255, 0) |
Blue Only (0, 0, 255) |
These three colors are the only actual colors you monitor can produce. All others are a perceptual illusion created by mixing those three colors. Here is what appears to be a spectrum of colors from red to blue:
Spectrum | |
Red Orange Yellow Green Blue |
However, all the colors in this spectrum are mixes of the above red, green, and blue, as is seen when the three colors are displayed separately:
Red Values | |
Green Values | |
Blue Values |
For us (and for many applications), all the colors that the monitor can produce are expressed as triples of red, green, and blue. If you want a color between red and green, mix red and green. For example, bright yellow is (Red=255, Green=255, Blue=0). Orange is closer to red than to green, so use more red: (Red=255, Green=175, Blue=0). If you want a color between green and blue, mix those two lights.
If you want a dark color, use less light. Dark orange is (Red=175, Green=75, Blue=0). (Dark orange is usually called "brown".) If each of the colors of light has a value, the result is a mix of white light and a color. For example, (Red=255, Green=200, Blue=200) is (Red=55, Green=0, Blue=0) mixed with (Red=200, Green=200, Blue=200).
The colors of the rainbow are red, orange, yellow, green, blue, violet. The above spectrum only had red through blue. Your computer monitor cannot make violet light, and no mix of RGB will produce the perception of violet. Often people use purple instead. Purple is a mix of red and blue, for example (255, 0, 255) is a bright purple.
In HTML (HyperText Markup Language), the language used to
create web pages, colors are often specified with six hex digits
in the format #RRGGBB
where RR are two
digits for red, GG are two digits for green, and BB are two digits for blue.
A hex digit may be 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F.
So color values may be 00 up to FF.
This range corresponds to the decimal range 0 to 255.
For example, to set a span of text to the color red,
do this:
<span style="color:#FF0000">Text to display as red.</span>
Here is what that does: Text to display as red. Here is another color: #00F000, and another: #00FFFF. There are other ways to specify colors in HTML, and many other places where colors are specified using hex digits. Sometimes application programs allow hex digits for colors.
For color images, these notes use Portable Pixel Map files, PPM files.
PPM files are nearly identical to PGM files except that, for PPM files, three bytes are used for each pixel of the image. The three bytes hold red, green, and blue values, in that order, in the range 0 to 255 using unsigned binary.
An PPM file starts out with some additional information. The following table shows what is in a PPM image file, byte by byte:
ASCII characters: 'P' followed by '6' followed by one or more whitespace characters (usually ending with a newline character). Zero or more comment lines. Each line starts with a # and ends with a newline character. Width of image in pixels (ASCII characters indicating a decimal value) followed by one or more whitespace characters (usually ending with a newline character). Height of image in pixels (as ASCII characters indicating a decimal value) followed by one or more whitespace characters (usually ending with a newline character). Maximum value of a color (as ASCII characters indicating a decimal value) followed by a single whitespace character, usually a newline. For us the maximum value will always be 255, which means each color will take a byte. The pixel data, three bytes per pixel, using unsigned binary, giving the values of red, green, and blue, in that order.
The PPM file starts out with literally the ASCII characters "P6" followed by whitespace characters (often a newline). These two bytes are sometimes called the "magic number" that identifies the image format. Sometimes these bytes are called the "signature".
Next there may be several lines of comments. Each line starts with the character "#" and is followed by ordinary ASCII text. Each lines ends with newline. Some programs may not be able to deal with comments.
Following this is the width, height, and maximum pixel value. Each of these is represented with ASCII characters. Each value is separated from the next with one or more whitespace characters, except the maximum value should be followed by just one whitespace character, which is usually the newline character.
The pixel data consists of three bytes for each byte of the image. Bytes (when regarded as small integers) have values 0 to 255. Notice that pixel values for PPM files are NOT encoded as ASCII.
The pixels of the 2D image are stored in raster order: the bytes in row 0 are stored first (from left to right), then row 1, then row 2, and so on. Sometimes this pixel data is called the raster.
Here is how a 3 row by 4 column gray level image is stored. Say that all the pixels of row zero are maximum red (255 for red and zero for green and blue), and that all the pixels of row one are white (255 for each color), and that all the pixels of row two are purple (255 for red and blue, zero for green). This image file has no comments. Notice that there is nothing in the pixel data that separates one row of pixels from the next.
byte numbervalue Comment 0 'P'ASCII character 'P' (the bit pattern 0x50) 1 '6'ASCII character '6' (the bit pattern 0x36) 2 ' 'space (the bit pattern 0x20) 4 '4'width, in ASCII (the bit pattern 0x34) 4 ' 'space 5 '3'height, in ASCII (the bit pattern 0x33) 6 ' 'space (the bit pattern 0x20) 7 '2'number of 8 '5'color levels, 9 '5'in ASCII 10 ' 'space Row Zero 11 255pixel row 0 col 0 - Red 12 0- Green 13 0- Blue 14 255pixel row 0 col 1 - Red 15 0- Green 16 0- Blue 17 255pixel row 0 col 2 - Red 18 0- Green 19 0- Blue 20 255pixel row 0 col 3 - Red 21 0- Green 22 0- Blue Row One 23 255pixel row 1 col 0 - Red 24 255- Green 25 255- Blue 26 255pixel row 1 col 1 - Red 27 255- Green 28 255- Blue 29 255pixel row 1 col 2 - Red 30 255- Green 31 255- Blue 32 255pixel row 1 col 3 - Red 33 255- Green 34 255- Blue Row Two 35 255pixel row 2 col 0 - Red 36 0- Green 37 255- Blue 38 255pixel row 2 col 1 - Red 39 0- Green 40 255- Blue 41 255pixel row 2 col 2 - Red 42 0- Green 43 255- Blue 44 255pixel row 2 col 3 - Red 45 0- Green 46 255- Blue
Of course, this is a ridiculously small image, used only to discuss the disk file format.
The following C program creates the above tiny PPM image file.
#include <stdlib.h> #include <stdio.h> int main(int argc, char *argv[]) { putchar( 'P' ); /* Signature */ putchar( '6' ); /* Signature */ putchar( ' ' ); /* space */ putchar( '4' ); /* width */ putchar( ' ' ); /* space */ putchar( '3' ); /* height */ putchar( ' ' ); /* space */ putchar( '2' ); /* max */ putchar( '5' ); /* gray */ putchar( '5' ); /* level */ putchar( ' ' ); /* space */ putchar( 255 ); putchar( 0 ); putchar( 0 ); /* row 0 col 0 */ putchar( 255 ); putchar( 0 ); putchar( 0 ); /* row 0 col 1 */ putchar( 255 ); putchar( 0 ); putchar( 0 ); /* row 0 col 2 */ putchar( 255 ); putchar( 0 ); putchar( 0 ); /* row 0 col 3 */ putchar( 255 ); putchar( 255 ); putchar( 255 ); /* row 1 col 0 */ putchar( 255 ); putchar( 255 ); putchar( 255 ); /* row 1 col 1 */ putchar( 255 ); putchar( 255 ); putchar( 255 ); /* row 1 col 2 */ putchar( 255 ); putchar( 255 ); putchar( 255 ); /* row 1 col 3 */ putchar( 255 ); putchar( 0 ); putchar( 255 ); /* row 2 col 0 */ putchar( 255 ); putchar( 0 ); putchar( 255 ); /* row 2 col 1 */ putchar( 255 ); putchar( 0 ); putchar( 255 ); /* row 2 col 2 */ putchar( 255 ); putchar( 0 ); putchar( 255 ); /* row 2 col 3 */ }
The statement putchar( 'P' )
puts a single byte, containing the
ASCII code for the character 'P'.
The statement putchar( 255 )
puts a single byte, containing the
value 255 encoded as unsigned binary.
Use Dev-C++ to create this program. Then run it and use redirection to send
the output to a disk filesmallColor.ppm
:
C:\>makeSmallColor > smallColor.ppm
Potential Gotchas: Review the potential problems with gray level images, PGM, since the same problems exist for the PPM format.
The image file smallColor.ppm
is so small that IrfanView does not
really show a picture when it opens the file.
If you click the "zoom" button enough times, you can magnify the image about 9 times:
The following C program creates a 256 by 256 PPM image file. All of the pixels in this file have the value (100, 200, 100) (light green):
#include <stdlib.h> #include <stdio.h> int main(int argc, char *argv[]) { int row, col; printf("P6 256 256 255 "); /* P6 rows cols maxColor */ for ( row=0; row<256; row++ ) for ( col=0; col<256; col++ ) { putchar( 100 ); putchar( 200 ); putchar( 100 ); } }
This program outputs the image header information using a single printf()
statement.
Run the program,
redirecting the output to a disk file:
C:\>makeLightGreen> lightGreen.ppm
Now when you use IrfanView to look at the file you should get a nice, big, green image.
Our programs will create images using the PPM format. However, you can use IrfanView to convert these color image to color GIF images (or other formats), just as for gray level images. You can now write programs that create color images in various ways, and convert them to any format you please!