bitmap conversions

Started by
4 comments, last by skitzo_smurf 23 years, 9 months ago
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
"Innocent is just a nice way to say ignorant, and stupidity is ignorance with its clothes off."words of,skitzo_smurf
Advertisement
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...
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, valuesDDPIXELFORMAT ddpf;DD_INIT_STRUCT(ddpf);lpdds->GetPixelFormat(&ddpf);//make an alias to the masksDWORD blueMask=ddpf.dwBBitMask;DWORD redMask=ddpf.dwRBitMask;DWORD greenMask=ddpf.dwGBitMask;		//variables to hold the number of zeros to the //right of the maskint bitsRightOfRed = 0;int bitsRightOfGreen = 0;int bitsRightOfBlue = 0;//variables to hold the number of bits in the mask itselfint 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 pixelint bitmapBpp = bitmap->bitmapInfoHeader.biBitCount>>3;//surface bits per pixelint surfaceBpp = colorDepth>>3; //colorDepth equals 16 here/* WARNING: THE REST OF THIS IS UUUUGGGLEEEE *///obtain a lock to the surfaceDD_INIT_STRUCT(ddsd);//lock the surface hereif(FAILED(lpdds->Lock(NULL,&ddsd,                      DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,		      NULL)))   return(0);//alias to the surface pointerBYTE* 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
"Innocent is just a nice way to say ignorant, and stupidity is ignorance with its clothes off."words of,skitzo_smurf
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
"Innocent is just a nice way to say ignorant, and stupidity is ignorance with its clothes off."words of,skitzo_smurf
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
AHA!, thank you that solved my problem!

skitzo_smurf
"Innocent is just a nice way to say ignorant, and stupidity is ignorance with its clothes off."words of,skitzo_smurf

This topic is closed to new replies.

Advertisement