Converting colors... 8bit index -> 24 bit.

Posted on 1998-05-23
Last Modified: 2013-12-03
here is what i need to do -
I have a palette that I have loaded from a PCX file.

Now, I want to plot pixels on the screen using Windows pixel plotting functions, but to do this, I need to convert from the indexed color to RGB values.

Now, when I just take the index, and apply the various color settings to an RGB structure and pass that, my colors appear to dark, which means that the info is too light.  i have tried doubling the values (ie: palette[index].red*2, etc.) but that doesn't seem to have worked.

I have loaded a pcx file into another program, but it looks "normal" there - ie: the colors are all correct, but when I load them in my little program, and convert them to 24 bit for use with pixel plotting they are all wrong.

Anyone that can help, I would be most appreciative.

This shouldn't be too hard of a question, I'm sure it's just a simple formula for converting from the 262K color possibilites of 256 color indexed to 24 bit color.  I just don't know it.
Question by:navigator010897
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 9
  • 5
LVL 22

Accepted Solution

nietod earned 50 total points
ID: 1403567
answer coming.
LVL 22

Expert Comment

ID: 1403568
First of all, different color indexes have no relationship to each other.  The first index might specify a dark red, the next might be sky blue, and the third might be light red.  No patern.  Thus doubleing the pallete indexes is of no value.  That will probably provide a totally unrelated color.  

Instead, if you really do want to make colors brighter, you can get the RGB value for a particular index and double each of the RGB components.  But you must make sure to limit the doubled values to 255.  Thus 200 would be converted to 256, not 400.

LVL 22

Expert Comment

ID: 1403569
However, I suspect that you really don't want to brighten the colors that way.  I suspect that the colors specified are okay and the problem is in how you are displaying them.  

The problem is probalby either

1 a bug where you are somehow getting the wrong color information or are specifying the wrong color information when you display pixels.  If this is the case, posting your code might help.

2.  The colors you are displayying are not in the current display's pallete and are being mapped to the closest colors--which apparently aren't close enough.  If that is the case, you can use RealizePallete() to try to get the colors you need on the display.
PeopleSoft Has Never Been Easier

PeopleSoft Adoption Made Smooth & Simple!

On-The-Job Training Is made Intuitive & Easy With WalkMe's On-Screen Guidance Tool.  Claim Your Free WalkMe Account Now


Author Comment

ID: 1403570
Well, my doubling was on each of the individual colors that make up a single entry in the index, not doubling the index number itself (yes, I do know something about color)

Now, I'm viewing this on a (currently) 16 bit color display.  one of the colors in the palette is pure white, but it isn't showing as pure white.  Colors like teal that I know are displayable (as they are displayed in other graphic programs) are not coming out right.

      multnum = TileBuffer[x*32+y];
      tR = PalEnt[multnum].Red*2;
      tG = PalEnt[multnum].Green*2;
      tB = PalEnt[multnum].Blue*2;
      point.x = xPos+x;
      point.y = yPos+y;
      pDC->SetPixel(point, RGB(tR,tG,tB));

LVL 22

Expert Comment

ID: 1403571
What happens when you do a SetPixel with a hard-coded color you know, like white.  Does it come out as pure white?  If so, the problem is in the getting the RGB color from the pallete  (Perhaps you are off by one, like using a 1 relative index instead of a 0 relative index--that type of thing).  If the color is still wrong then it has to do with how you are displaying the colors.  Perhaps you need to realize a custom pallete.

Although you probably don't want to be doubling the color values, if you do so, make sure they don't go over 255.

Author Comment

ID: 1403572
Well, ok, let's say I find all the documentation in my various books, and figure out how to get my palette into a CPalette, and realize it - is there a version of setpixel that I can tell it to use lookup values instead of passing an RGB converted value?

If the colors were off, ie: grabbing from the wrong entries, then none of the colors would even be close I'd imagine...
LVL 22

Expert Comment

ID: 1403573
SetPixel takes a COLORREF The most commong type of color reference is the RGB.  But I believe it is possible to create COLORREF's that indicate they are indexes into the palette.  (If the high byte is zero it is a RGB color ref.  Other values indicate other types.)  However, I think this is discouraged.

If you a grabing the wrong entry, things might look very differrent.  But sometimes pallets are organized so similar colors are adjacent.  So it might not look too bad.  However, this probably is not the case, but it might be worth looking at.

I'm curios what you found when you SetPixel()ed  with hardcoded RGB values.  Did it look okay?

Author Comment

ID: 1403574
Well, in regards to setpixel()'d functions - it is the current only way I can display my tiles in my editor, at least until I get enough info on how to use DIB's and palettes into CDC's.

I have found that my drawing functions that are pulling color references from my "external" palette work pretty well, although the color is quite dim (I finally settled on a *3 - 5. to get close to a correct brightness.

But, I have found it to be quite slow.  I'm not looking for some function somewhere to lock onto the verticle retrace because I get a lot of shearing whenever my tiles are being re-drawn (and my screen has like 14x20 tile amounts) and setpixel is VERY slow.  

Hopefully some of the shearing will disappear when I finally figure out the delay for verticle retrace in an MFC app.  The nice thing is that I am able to draw my pictures pixel by pixel (Which allows for editing) instead of having to get it into a structure to display it, which makes editing a little more limited.

But, I look forward to figuring out DIB's and selecting and realizing palettes into the CDC for increased speed in blitting.

Author Comment

ID: 1403575
Damn, I posted a long respons earlier nietod, if you're interested in hearing it again, email me (

But, in regards to my question, someone else came up with the answer - that the color registers took values of 0-63 for each R G and B entry, and that the appropriate multiplication was 4, and when I did that, everything went great.

I'll grade this question later when I get home.
LVL 22

Expert Comment

ID: 1403576
Where did you post this long response?

So the Image uses a different RGB format then?  I wasn't aware of that.  Multiplying the color values seemed like a bad idea and it was the answer after all.

I'm not sure where/how you got the other answer.  But if it was from another expert, you should let them answer the question and get the points.
LVL 22

Expert Comment

ID: 1403577
I'm looking back and see a comment now that I mised before.  Yes, setpixel() will be VERY slow for large images (probably even small ones)  Once you switch to DIB (That won't be hard, you are most of the way there) it will go MUCH faster.  You won't need to worry about the vertical retrace.  Let the BitBlt() (or associated procedures) handle that for you.  Windows makes getting hold of that sort of information nearly impossible, and usually unnecessary.

Author Comment

ID: 1403578
Well, I got the info on the color from another website I frequent and left a message at.  Someone made the suggestion, and it worked beautifully, all the colors are right now.

I'm trying to track down the DIB info I need so I can fill DIB structures in with my tiles that I need to draw.  This setpixel is getting REALLY friggen annoying, mostly when I have to scroll and I see it re-drawing each line and having to pause for a few seconds on a P150 MMX!!!!

Do you Nietod know where I could find this DIB info?  I have another question regarding it, and another expert has given a pseudo answer, but hasn't responded to my last question yet.  If you could supply an answer, I'd be happy to "unlock" the question to get the answer I need...
LVL 22

Expert Comment

ID: 1403579
What info do you need?  I can paste in the documentation for SetDIBBits()..  That is what you will use to convert your RGB informaion to a bitmap inside of a DC.
LVL 22

Expert Comment

ID: 1403580
SetDIBits <Picture> <Picture> <Picture>

The SetDIBits function sets the pixels in a bitmap using the color data found in the specified device-independent bitmap (DIB).

int SetDIBits(
HDC hdc, // handle of device context
HBITMAP hbmp, // handle of bitmap
UINT uStartScan, // starting scan line
UINT cScanLines, // number of scan lines
CONST VOID *lpvBits, // array of bitmap bits
CONST BITMAPINFO *lpbmi, // address of structure with bitmap data
UINT fuColorUse // type of color indices to use

hdc - Identifies a device context.

hbmp - Identifies the bitmap that is to be altered using the color data from the specified DIB.

uStartScan - Specifies the starting scan line for the device-independent color data in the array pointed to by the lpvBits parameter.

cScanLines - Specifies the number of scan lines found in the array containing device-independent color data.

lpvBits - Points to the DIB color data, stored as an array of bytes. The format of the bitmap values depends on the biBitCount member of the BITMAPINFO structure pointed to by the lpbmi parameter.

lpbmi - Points to a BITMAPINFO data structure that contains information about the DIB.

fuColorUse - Specifies whether the bmiColors member of the BITMAPINFO structure was provided and, if so, whether bmiColors contains explicit red, green, blue (RGB) values or palette indices. The fuColorUse parameter must be one of the following values:

Value - Meaning
DIB_PAL_COLORS -The color table consists of an array of 16-bit indices into the logical palette of the device context identified by the hdc parameter.
DIB_RGB_COLORS - The color table is provided and contains literal RGB values.

Return Values

If the function succeeds, the return value is the number of scan lines copied.
If the function fails, the return value is zero. To get extended error information, call GetLastError.

Optimal bitmap drawing speed is obtained when the bitmap bits are indices into the system palette.

Applications can retrieve the system palette colors and indices by calling the GetSystemPaletteEntries function. After the colors and indices are retrieved, the application can create the DIB. For more information, see System Palette.

The device context identified by the hdc parameter is used only if the DIB_PAL_COLORS constant is set for the fuColorUse parameter; otherwise it is ignored.

The bitmap identified by the hbmp parameter must not be selected into a device context when the application calls this function.

The origin for bottom-up DIBs is the lower-left corner of the bitmap; the origin for top-down DIBs is the upper-left corner of the bitmap.

See Also
GetDIBits, GetSystemPaletteEntries, BITMAPINFO

Featured Post

MS Dynamics Made Instantly Simpler

Make Your Microsoft Dynamics Investment Count  & Drastically Decrease Training Time by Providing Intuitive Step-By-Step WalkThru Tutorials.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article shows how to make a Windows 7 gadget that extends its U/I with a flyout panel -- a window that pops out next to the gadget.  The example gadget shows several additional techniques:  How to automatically resize a gadget or flyout panel t…
For a while now I'v been searching for a circular progress control, much like the one you get when first starting your Silverlight application. I found a couple that were written in WPF and there were a few written in Silverlight, but all appeared o…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA.…
Monitoring a network: how to monitor network services and why? Michael Kulchisky, MCSE, MCSA, MCP, VTSP, VSP, CCSP outlines the philosophy behind service monitoring and why a handshake validation is critical in network monitoring. Software utilized …

623 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question