Using Color Tables on a 24-Bit Display

QUESTION: I am trying to change color tables for my 2D images, but I can't get XLOADCT (or LOADCT, for that matter) to work on my display. It works on my colleague's display. What is going on?

ANSWER: You are running IDL on a display that is using more than 256 colors. Typically, this means you are running IDL on a display that supports 16-bit or 24-bit color. This kind of display can simultaneously display thousands or millions of different colors, rather than the 256 colors you may be used to. Colors are specified on a 16-bit or 24-bit display with what is called an RGB direct color model. Colors on a 8-bit color display are specified with what is called an indexed color model.

To put your 16-bit or 24-bit display into a mode that will support color tables, you must turn color decomposition off. Issue this command in your IDL session:

   Device, Decomposed=0

Now you can load color tables and see images in color when you display them:

   LoadCT, 5
   image = Congrid(Dist(200), !D.X_Size, !D.Y_Size)
   TV, image

But what doesn't happen is that the image colors don't change when you change the color tables!

   LoadCT, 1

This is because on a 16-bit or 24-bit display, the image colors are not indexed to the colors in the color table. In other words, the image colors don't change when the colors in the color table change. On 16-bit and 24-bit displays, the image colors are expressed directly as RGB triples. What you do by turning color decomposition off is force the values for the image color triples to be obtained or looked up in the color table.

If you want to see the image in the colors of the new color table, you must redisplay the image. Your code will look something like this:

      ; Load a red-temperature color table and display image.

   LoadCT, 3
   TV, image

      ; Load a Standard-Gamma II color table. Redisplay image.

   LoadCT, 5
   TV, image

It is really quite simple to write programs that can re-display the image (or any other graphical display, for that matter) when the colors are changed. At least it's simple if you have the right tools. :-)

Fortunately, you can get some of the right tools here on this web page. The most useful in this case is XColors, a color changing tool that can notify a widget program when the color table vectors have been changed. It does this through a NotifyID keyword.

Here is a short program that will automatically update the image when the color tables are changed on 16-bit or 24-bit displays.


      ; Handles color table loading events. Allows colors be to changed.

   Widget_Control,, Get_UValue=info, /No_Copy
   thisEvent = Tag_Names(event, /Structure_Name)
   CASE thisEvent OF


            ; Color table tool. The NOTIFYID keyword identifies a widget
            ; that should be notified when the color table vectors are
            ; changed.

         XColors,, NotifyID=[,]


            ; Update the display for 16-bit and 24-bit displays
            ; when color table vectors are loaded and XCOLORS
            ; sends notification of that fact.

         Device, Get_Visual_Depth=thisDepth
         IF thisDepth GT 8 THEN BEGIN
            WSet, info.wid
            TV, info.image


   Widget_Control,, Set_UValue=info, /No_Copy


      ; Create some data.
   image = Rebin(Dist(200), 400, 400)

      ; Create widgets.
   tlb = Widget_Base(Column=1, Base_Align_Center=1, $
      XOffset=200, YOffset=200)
   button = Widget_Button(tlb, Value='Change Image Colors', $
   drawID = Widget_Draw(tlb, XSize=400, YSize=400)
   Widget_Control, tlb, /Realize
   Widget_Control, drawID, Get_Value=wid

      ; Load color table and display image.
   LoadCT, 5
   WSet, wid
   TV, image

      ; Create info structure.
   info = {image:image, wid:wid}
   Widget_Control, tlb, Set_UValue=info, /No_Copy
   XManager, 'color_example', tlb, /No_Block

[Return to IDL Programming Tips]