Archived

This topic is now archived and is closed to further replies.

skitzo_smurf

bitmap conversions

Recommended Posts

I am trying to convert bitmaps from one color depth to another color depth. Ex 24 bit to 16 bit or 24 bit to 32 bit. I have a VERY general idea of how to do this, but I would appreciate any suggestions, links, or otherwise. thanks in advance, skitzo_smurf

Share this post


Link to post
Share on other sites
All you need to do is run through the bitmap and extract the RGB values to all the pixels, and re-encode them in the new color depth. However, if you''re going between something and 8 bit, it''s a little harder. You''ll have to somehow get choose a palette based on all the colors in the image. I don''t know how to do that though...

Share this post


Link to post
Share on other sites
ok, heres roughly what im doing and its not working right. First off i used this article for help:
http://www.gamedev.net/reference/articles/article538.asp

1. My graphics are all done in 24 bit color..
2. This is SUPPOSED to convert from 24 to 16 bit

        

//get the masks for the r,g,b, values
DDPIXELFORMAT ddpf;
DD_INIT_STRUCT(ddpf);
lpdds->GetPixelFormat(&ddpf);

//make an alias to the masks

DWORD blueMask=ddpf.dwBBitMask;
DWORD redMask=ddpf.dwRBitMask;
DWORD greenMask=ddpf.dwGBitMask;

//variables to hold the number of zeros to the

//right of the mask

int bitsRightOfRed = 0;
int bitsRightOfGreen = 0;
int bitsRightOfBlue = 0;

//variables to hold the number of bits in the mask itself

int bitsInRedMask = 0;
int bitsInGreenMask = 0;
int bitsInBlueMask = 0;

//set the bit information

// I know for sure that getMaskInfo() is working
// the way it should. I have ruled it out as the problem.

// The parameters are VERY self explanatory.


getMaskInfo(bitsRightOfRed,bitsInRedMask,redMask);
getMaskInfo(bitsRightOfGreen,bitsInGreenMask,greenMask);
getMaskInfo(bitsRightOfBlue,bitsInBlueMask,blueMask);

//bitmap bits per pixel

int bitmapBpp = bitmap->bitmapInfoHeader.biBitCount>>3;

//surface bits per pixel

int surfaceBpp = colorDepth>>3; //colorDepth equals 16 here


/* WARNING: THE REST OF THIS IS UUUUGGGLEEEE */

//obtain a lock to the surface

DD_INIT_STRUCT(ddsd);

//lock the surface here

if(FAILED(lpdds->Lock(NULL,&ddsd,
DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,
NULL)))
return(0);

//alias to the surface pointer

BYTE* dest_ptr = (BYTE*)ddsd.lpSurface;

for(unsigned int i = 0;
i < bitmap-bitmapInfoHeader.biSizeImage;
i += bitmapBpp)
{
WORD r,g,b;

//get the rgb value of one pixel of the bitmap

//NOTE: source is pointing to the bitmap's buffer

r = *source_ptr;
source_ptr++;
g = *source_ptr;
source_ptr++;
b = *source_ptr;
source_ptr++;

//shift off the least significant bits of each component

r >>= (8-bitsInRedMask);
g >>= (8-bitsInGreenMask);
b >>= (8-bitsInBlueMask);

//now place the new number back where you got it

r <<= bitsRightOfRed;
b <<= bitsRightOfBlue;
g <<= bitsRightOfGreen;

WORD compiledPixel = (WORD)(r|g|b);

*dest_ptr = (BYTE)(compiledPixel);
*(dest_ptr+1) = (BYTE)(compiledPixel<<8);

dest_ptr += surfaceBpp;
}



Ive tried a bunch of stuff to get this to work, but the graphics come out blue. They are the right shape, just the wrong color. Im pretty sure the problem is the way im assigning the pixel to *dest_ptr.

I will greatly appreciate any help,
skitzo_smurf

Edited by - skitzo_smurf on July 21, 2000 3:10:28 AM

Share this post


Link to post
Share on other sites
ok,
I finally got this to work. Actually I MADE this work. I still havent solved my problem. I figured out that for some reason the red and blue channels were getting switched. BUT WHY?! If anyone sees that im doing something stupid, please let me know

thanks,
skitzo_smurf

Share this post


Link to post
Share on other sites
for(unsigned int i = 0;
i < bitmap-bitmapInfoHeader.biSizeImage;
i += bitmapBpp)

This is wrong - if bitmapWidth is not multiple of 4.
You should do loop by rows and use aligned width as offset to next row.

r = *source_ptr;
source_ptr++;
g = *source_ptr;
source_ptr++;
b = *source_ptr;
source_ptr++;

Bitmap has opposite order of the color components:
r = source_ptr[2];
g = source_ptr[1];
b = source_ptr[0];

And I guess, destination surface also must be aligned.


Edited by - Serge K on July 21, 2000 7:15:02 AM

Share this post


Link to post
Share on other sites