Link to home
Start Free TrialLog in
Avatar of navigator010897
navigator010897

asked on

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

Ok,
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.
ASKER CERTIFIED SOLUTION
Avatar of nietod
nietod

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of nietod
nietod

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.

continues
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.
Avatar of navigator010897

ASKER

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));

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.
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...
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?
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.
Damn, I posted a long respons earlier nietod, if you're interested in hearing it again, email me (tony@ntech.com)

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.
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.
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.
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...
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.
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
);

Parameters
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.

Remarks
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