Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

format of BITMAP.bmBits for 24 bit RGB

280 views
Skip to first unread message

Patrik Stellmann

unread,
Aug 4, 2003, 3:36:28 AM8/4/03
to
I have a BITMAP structure containing a 24Bit RGB bitmap and want to
manupulate it by directly accessing BITMAP.bmBits. Could anybody give me
the formular to calculate the position of R, G and B value for a
specific x,y pixel in bmBits?

Currently I'm using CDC:GetPixel/SetPixel to do it but this is far too
slow...

Thx for any help!

Micus

unread,
Aug 4, 2003, 6:34:17 AM8/4/03
to

"Patrik Stellmann" <go...@volleynet.de> wrote in message
news:bgl2fb$poheg$1...@ID-194971.news.uni-berlin.de...

> I have a BITMAP structure containing a 24Bit RGB bitmap and want to
> manupulate it by directly accessing BITMAP.bmBits. Could anybody give me
> the formular to calculate the position of R, G and B value for a
> specific x,y pixel in bmBits?

Take this with a grain of salt, but off the top of my head...
With 24-bit color depth, RGB is arranged in 8 - 8 - 8 bits. Each row
is WORD aligned so, depending on the dimensions of the bitmap, each row may
have some zeros at the end for a buffer. You can get the number of bytes per
row from the BITMAP::bmWidthBytes field. The bitmap bits for the pixels are
ordered left to right starting with the top row working down to the bottom
row (i.e. pixel at (0,0) is the first 24 bits of the array). So, I believe
you can read the colors of the first pixel from the first 3 BYTEs of the
array... so on so forth for the rest of the pixels.

HTH, M

Patrik Stellmann

unread,
Aug 4, 2003, 8:59:15 AM8/4/03
to

Micus wrote:
> "Patrik Stellmann" <go...@volleynet.de> wrote in message
> news:bgl2fb$poheg$1...@ID-194971.news.uni-berlin.de...
>
>>I have a BITMAP structure containing a 24Bit RGB bitmap and want to
>>manupulate it by directly accessing BITMAP.bmBits. Could anybody give me
>>the formular to calculate the position of R, G and B value for a
>>specific x,y pixel in bmBits?
>
>
> Take this with a grain of salt, but off the top of my head...
> With 24-bit color depth, RGB is arranged in 8 - 8 - 8 bits. Each row
> is WORD aligned so, depending on the dimensions of the bitmap, each row may
> have some zeros at the end for a buffer. You can get the number of bytes per
> row from the BITMAP::bmWidthBytes field. The bitmap bits for the pixels are
> ordered left to right starting with the top row working down to the bottom
> row (i.e. pixel at (0,0) is the first 24 bits of the array). So, I believe
> you can read the colors of the first pixel from the first 3 BYTEs of the
> array... so on so forth for the rest of the pixels.
>

That's what I also thought and - except that it starts the lines are
stored from the bottom up - it's indeed the case. Made a stupid typing
error in my previuos try but now it works.

Thx!

a.m.a

unread,
Aug 4, 2003, 12:40:30 PM8/4/03
to

"Patrik Stellmann" <go...@volleynet.de> wrote :

> Currently I'm using CDC:GetPixel/SetPixel to do it but this is far too

Unless you know for sure that all the users will run Pentium 4 with
GForce4 NVidia video cards, dont use GetPixel, its very slow.

Here's a sample i posted many times. There's probably something in it
you can use. GoodLuck.

----------------------------------------------------------------------------
-------------

#include "stdafx.h"

DIBSECTION dib;
HBITMAP hdib;
HDC hSrcDC;
HDC hDeskTopDC;
void* oldObj;
BOOL ok=FALSE;

void CreateDIB(int w, int h);
void ScanDIB(int w, int h);

#define ALIGNULONG(i) ((i+3)/4*4)

int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
hDeskTopDC = GetWindowDC(GetDesktopWindow());

CreateDIB(200,200);
ScanDIB(200,200);

//paste the buffer directly on desktop to see results.
BitBlt(hDeskTopDC, 0, 0, 200, 200, hSrcDC, 0, 0, SRCCOPY);
::ReleaseDC(GetDesktopWindow(), hDeskTopDC);

//clean up
HGDIOBJ h = SelectObject(hSrcDC, oldObj);
DeleteObject(hdib);
DeleteDC(hSrcDC);

return 0;
}

void CreateDIB(int w, int h)
{
BITMAPINFO bi32 =
{
sizeof(BITMAPINFO),
w , -h,
1, 32, BI_RGB,
0, 0, 0, 0, 0
};

void* pBits = NULL;
hSrcDC = CreateCompatibleDC(hDeskTopDC);
hdib = CreateDIBSection(NULL, &bi32, DIB_RGB_COLORS, &pBits, NULL, 0);
oldObj = SelectObject(hSrcDC, hdib);

//wipe with a 200*200 brush
RECT rect = {0,0,w,h};
ok = FillRect(hSrcDC, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH));

//here: "dib.dsBm.bmBits" will points to the pixels of hdib.
ok = GetObject(hdib , sizeof(DIBSECTION), &dib);
}

void ScanDIB(int w, int h)
{
//each scan line in a bitmap has a width, a.k.a : pitch
int pitch = ALIGNULONG(dib.dsBm.bmWidthBytes);
//pointer to pixel data.
BYTE* pSrcBits = (BYTE*)dib.dsBm.bmBits;
//pointer that will advance in memory one pixel at a time...
BYTE* pSrcPix;

//loop through all pixels
for(int y=0; y<h; y++)
{
//get scan line
pSrcPix = pSrcBits + (pitch * y);

for(int x=0; x<w; x++)
{
//here each pixels is 32 bytes each since we created a 32 bit DIB.
//Since 4 * 8(bits) = 32, we can use byte array.
//Here i convert the bitmap to grey scale gradient:
//change one color then make them all equal to pSrcPix[0];
//it would be a good exercise to put a break point here observe what
happens...

pSrcPix[0] = x % 255;
pSrcPix[2] = pSrcPix[1] = pSrcPix[0];

//advance to next pixel (4 bytes per pixel = 32 bit per pixel)
pSrcPix += 4;
}
}
}


0 new messages