Link to home
Start Free TrialLog in
Avatar of GoldStone32767
GoldStone32767

asked on

get bits of a bitmap

All i need to do is determine the RGB colors of each bit in a BITMAP stored in memory. I allready asked this question, but no one could completely answer the question. I only got parts of answers that really never added up. This uses up all 500 points i used to have... So hopefully someone knows this now. Doesnt seem too hard of a problem does it?
Avatar of smitty1276
smitty1276

BITMAPFILEHEADER fh;
BITMAPINFOHEADER ih;
unsigned char    *bits;

//load the bitmap
ifstream in(fileName, ios::in | ios::binary);
if(in.fail())
{
  bits = NULL;
  return;
}

in.read( (unsigned char*)&fh, sizeof(BITMAPFILEHEADER) );

//check for valid bitmap
if( fh.bfType != 'MB' )
{
  bits = NULL;
  return;
}

in.read( (unsigned char*)&ih, sizeof(BITMAPINFOHEADER) );

int bitsize;
if( (bitsize = ih.biSizeImage) == 0 )
  bitsize = (ih.biWidth * ih.biBitCount + 7) /
            8 * abs(ih.biHeight);

bits = new unsigned char[(const)bitsize];
in.read( (unsigned char*)bits, bitsize );
}


If you use this code, bits will contain an array of unsigned characters (0-255) containing the BGR values of each bit. 3 bytes per pixel... B then G then R.


   
Avatar of DanRollins
Smitty1276:
It's a long shot, but ...

>>a BITMAP stored in memory

would seem to indicate that the bitmap is stored in memory, rather than in a file.

Goldstone32767:
Assuming that you have an HBITMAP to it, you can simply call:

int nByteCnt= 10000; // or whatever the size...

BYTE *pBitBuf= malloc( nByteCnt );
LONG GetBitmapBits(hbmp, nByteCnt, pBitBuf );

Alas, this does not guarantee that you will get a nice, clean 1-byte per pixel.  If the bitmap is a True color, each pixel will use three bytes.  If it is is HighColor, it will use two bytes.  If it is 256-color, it will use one byte (an index into a color palette, not an RGB value),  If it is a 16-color bitmap, it will use 4-bits per pixel and if it is monochrome, it will use 1 bit per pixel.

Perhaps the easiest way to work on this is to come in from the end result and work backward.  What do you want to do with the pixels once you have them?

-- Dan
GetBitmapBits is obsolete now and is only there for backward compatibility , use GetDIBits now , this also lets you sprcify the desired format of the bitmap and that definitely includes the no of bits per pixel that you want.
The BITMAPINFO structure that you pass to GetDIBits must have in its bitmapinfoheader field the following fields set. Note width and height are to be the same as that of hBitmap

biWidth = (width of the bitmap)
biHeight = (height of the bitmap)
biBitCount = [desired color resolution (1, 4, 8, or 24)]
Avatar of GoldStone32767

ASKER

Actually i have a CBitmap where i store my picture. Does this affect the code in any way?
no CBitmap has an overloaded HBITMAP operator so its is usable whereever you would require and object of type HBITMAP .. if this is what you need to know
are you saying not to use the CBitmap to store my image?

and for the other question, i need the pixels so i can apply image effects to them. i will need to change all the bytes individually and then set them back to the bitmap. SetPixel does that but is way to slow, so i am looking for speed.
No i did not say not to use CBitmap , i mean that you can use it easily where an ordinary HBITMAP is required.

There is another API SetDIBits which does exactly the opposite of GetDIBits , get bits using GetDIBits in the required format , manipulate them and then set them using SetDIBits...

hope this helps
is there any source i can see how to use the GetDIBits API? i tried once before... but it always returns a 0. which means it didnt read anything

here is the src i currently have... maybe someone can find the problem:

CBitmap bmp;
BITMAP bmpStr;
BITMAPINFO bmi;

me.imgBMP.GetBitmap( &bmpStr );

bmi.bmiHeader.biSize = 0x28;
bmi.bmiHeader.biBitCount = 0;
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biSizeImage = bmpStr.bmWidthBytes*bmpStr.bmHeight;

BYTE *pData = new BYTE[bmi.bmiHeader.biSizeImage];

int numBits = GetDIBits(mDC,(HBITMAP)me.imgBMP,0,bmpStr.bmHeight,pData,&bmi,DIB_RGB_COLORS );
     
where me is my own object. imgBMP is the CBitmap in object 'me'    
>>but it always returns a 0. which means it didnt read anything

Call GetLastError() to learn why the GDI fn failed.  That is a general rule of thumb that will save you hours of frustation reading unhelpful comments like this one from self-proclamed experts like me.

-- Dan
THis link

http://home.earthlink.net/~danrollins/ee/FastBmpRotation.htm

Includes code that does all of the necessary stuff.  It gets down-and-dirty with the raw bits.

-- Dan
hi GoldStone32767,

Do you have any additional questions?  Do any comments need clarification?

-- Dan
ASKER CERTIFIED SOLUTION
Avatar of DanRollins
DanRollins
Flag of United States of America image

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
Comment from DanRollins accepted as answer.

Thank you
Computer101
Community Support Moderator
Hi, Im zak

I want to know where and how can I store bitmap data in Palm table field !!
i use on palm bitmap field type bitmapType !

thanks.