Coyote's Guide to IDL Programming

Extra PostScript Colors

QUESTION: I have extra colors in my image output. Where do these colors come from?

ANSWER: A PostScript device generally uses more colors than you actually use on your display device. The number of colors in your IDL session is determined at the time the first IDL graphics window is opened. The number of colors used in that session of IDL is then given by the !D.N_COLORS system variable. This number is typically a number between 200 and 242, but it can be almost anything, depending upon a number of factors.

When you load a color table in IDL (for example, with the LOADCT command), IDL reads the red, green, and blue vectors that describe the color table out of a file. Each vector is 256 elements in length. But these vectors are re-sampled to equal the number of colors you are using in your IDL session before they are loaded. Suppose you are using 220 colors in your IDL session. Then what LOADCT does is essentially this:

   red = CONGRID(red, 220)
   green = CONGRID(green, 220)
   blue = CONGRID(blue, 220)
   TVLCT, red, green, blue

What this means is that whenever you load a particular color table in IDL it "appears" to use all 256 colors. What many people do to display their image is to use a TVSCL command. This does exactly the same thing to the image data: it scales the image into the number of colors used in that IDL session. Thus, the image "appears" to use all 256 colors.

But the PostScript device always has 256 colors available, and this can cause your image to look different on your display and in your PostScript output. In fact, it can cause your image to appear to have "extra" colors in it. Consider these two commands with an image that has values between 0 and 255:

  TVSCL, image

If these commands were issued in IDL when your display is the current graphics device and you have 220 colors available in the IDL session, a pixel that has a "true" value of 100 will be displayed with a value of 85. If you look at the color triple (red, green, blue) associated with color index 85, you will find the value (174, 0, 0) for this particular color table. In other words, this pixel is rendered in a particular shade of red.

However, if you make the PostScript device the current graphics device, this pixel has a value of 100 when it is displayed, since the PostScript device uses 256 colors. If you look at the color triple associated with color index 100, you see the value (185, 0, 0). In other words, the pixel is rendered in a red color, but it is not the same red color it was rendered with on the display.

This means, of course, that your images will look slightly different in the two mediums and the difference will be more noticeable the fewer display colors you have available to you. (This discussion ignores that fact that PostScript output almost always looks different from the display just because one output is rendered as light and one is rendered as pigment. There is no good way to avoid these differences.)

Transferring Color Tables Affects PostScript Colors

Another reason that your images can look different on the display and in your PostScript output is the way the color tables are transferred from the display into the PostScript file. You learned from the discussion already that color table vectors are re-sampled to fit into the number of colors you are using in your IDL session. But if you make the PostScript device the current graphics device and either copy the color table into the file or select color PostScript output, the display colors are transferred directly into the PostScript color table.

In other words, suppose I have 220 colors in my IDL session and the display is my current graphics device. I could load a color table, like this:

   LOADCT, 5

I will have loaded 220 colors. Suppose I now switch to the PostScript device and copy the colors in the color table, like this:


Or, I could do the same thing by typing this:


In either case, what I have done is transferred the 220 colors loaded in my IDL session into the 256 color table vectors that are available in my PostScript device. If I now display my image by typing something like this:

   TVSCL, image

I will notice that all the pixels with values above 220 are displayed in incorrect colors! In fact, they will probably be displayed with gray-scale colors. If I want the display to look similar to what I saw on the display, I should re-load the color table after making the PostScript device the current device, like this:

   LOADCT, 5
   TVSCL, image

But as I have already pointed out, this won't give you identical results on your display and in PostScript.

Getting Identical Results in PostScript and on the Display

If you want identical results, then you must scale the data into some number of colors that exists on both the display and in the PostScript file. What I do is find out how many colors there are on the display, and use that many colors in PostScript as well. (Remember you have to open a graphics window in IDL to determine how many colors you will use in that display. The information is likely to be misleading until that window is opened.) My code looks something like this:

   displayColors = !D.N_COLORS
   TV, BYTSCL(image, TOP=displayColors-1)

Now my image looks identical to what I see on the display. And an added benefit is that I don't have to reload the color table, since I am only using colors that are transferred into the PostScript file when I selected color PostScript output.

Web Coyote's Guide to IDL Programming