Displaying Indexed Color Images

Indexed color images map data values in a two-dimensional array to a range of color values — often the range used is the range of byte values (0 - 255). Each pixel in the image takes its color value from the byte value of a single array element; the byte values are then mapped to values in a color table that specifies the display color for each byte value.

Often, greyscale (or black-and-white) image data is stored in a byte array and displayed through a color table. IDL's default color table is a greyscale ramp, meaning that the byte values 0 through 255 are mapped to 256 shades of grey, ranging from 0 (black) to 255 (white).

Use the TV, TVSCL and iImage routines to display indexed color images.

Displaying Indexed Color Images with TV

The TV routine creates a static display of the image data in the specified array. For example, to display a greyscale PNG image from the file mineral.png in IDL's examples/data subdirectory:

file = FILEPATH('mineral.png', SUBDIRECTORY=['examples', 'data'])
mineral = READ_PNG(file)
HELP, mineral
LOADCT, 0
TV, mineral


mineral_image1.gif

Here, we read the data from the PNG file mineral.png into an array named mineral. The output from the HELP procedure shows us that the resulting array is a 288 x 216 element byte array. The LOADCT routine loads IDL's default color table (a greyscale ramp), and finally the TV routine displays the array in a static window.

When IDL creates a window in which to display the image, by default it uses the size specified in the Graphics preferences. You can alter this behavior by using the WINDOW routine to create a window of a specified size. For example, if we want to create a window the same size as the mineral image array, we use the SIZE routine to determine the dimensions of the array, then use the XSIZE and YSIZE keywords to the WINDOW routine to specify the window dimensions:

mineral_size = SIZE(mineral)
WINDOW, XSIZE=mineral_size[1], YSIZE=mineral_size[2]
TV, mineral


mineral_image2.gif

IDL's default color table may not be appropriate or useful for all data. There are 40 pre-defined color tables available; see LOADCT for information. For example, to display our mineral array using the pre-defined color table named "ocean", do this:

mineral_size = SIZE(mineral)
WINDOW, XSIZE=mineral_size[1], YSIZE=mineral_size[2]
DEVICE, GET_DECOMPOSED=old_decomposed, DECOMPOSED=0
LOADCT, 30
TV, mineral
DEVICE, DECOMPOSED=old_decomposed


mineral_image3.gif

Such "false color" displays may serve to highlight features of your data array that are harder to see in the greyscale image.

Note on Decomposed Color

Most modern computer displays use decomposed color. This means that color values are interpreted as three 8-bit color values where the least-significant 8 bits contain the red value, the next 8 bits contain the green value, and the most-significant 8 bits contain the blue value. In order to map the 256 byte values in a color table to the values in the image array, we tell IDL to use an indexed color model instead.

To force IDL to use the indexed color model, set the DECOMPOSED keyword to the DEVICE routine equal to zero. In the example above, we first use the GET_DECOMPOSED keyword to retrieve the current value, saving it in a variable named old_decomposed. This allows us to set the color model back to its original state after displaying the image.

This step is only necessary when loading non-default color tables for use in IDL Direct Graphics windows (created by TV or TVSCL). Windows created by the iImage tool use IDL Object Graphics, which handle indexed color images in a different manner. Setting the DECOMPOSED keyword to DEVICE has no effect on iTool or other Object Graphics displays.

Displaying Indexed Color Images with TVSCL

Not every image stored in a byte array has elements spanning the full range of byte values (0 to 255). In these cases, displaying the byte image with TV can result in a display that looks either dark or washed out, depending on what range the byte values lie within. In these cases, you may want to use the TVSCL routine, which scales the values of the input array into the range supported by the display device.

For example, if we read byte data out of the binary file nyny.dat in IDL's examples/data subdirectory into an IDL variable named nyny and check the range of byte values using the MIN and MAX routines:

file = FILEPATH('nyny.dat', SUBDIRECTORY = ['examples', 'data'])
imageSize = [768, 512]
nyny = READ_BINARY(file, DATA_DIMS = imageSize)
PRINT, 'Minimum byte value: ', MIN(nyny)
PRINT, 'Maximum byte value: ', MAX(nyny)

we see that the byte values range from 91 to 255 rather than from 0 to 255. Displaying the nyny array using TV results in a washed-out image:

LOADCT, 0
TV, nyny


nyny_image1.gif

whereas displaying the same byte array with the TVSCL routine results in an image will greater contrast:

TVSCL, nyny


nyny_image2.gif

Displaying Indexed Color Images with iImage

Displays created with TV and TVSCL are static, and cannot be altered once they are drawn to the screen. For a more interactive display, use the IIMAGE routine to display the image data in an interactive window:

file = FILEPATH('nyny.dat', SUBDIRECTORY = ['examples', 'data'])
imageSize = [768, 512]
nyny = READ_BINARY(file, DATA_DIMS = imageSize)
IIMAGE, nyny


nyny_image3.gif

You can immediately notice several things about the iImage display:

In addition, a variety of filtering operations can be applied to the image data by selecting from the Operations menu.

Further Information

For additional information on displaying indexed color images, see: