Tech Support > Microsoft Windows > Development Resources > DIB to HBITMAP - goes black
DIB to HBITMAP - goes black
Posted by Gernot Frisch on July 26th, 2006


This is my code for making a dummy 24 bit DIB and trying to convert to
a HBITMAP.
The image shows up black, the size is OK.

# # #

int w,h,w2;
w=320; h=140; w2=320/*4 byte align*/;

char* pImageBits = new char[w2*h*3];
// dummy colors
for(int i=0; i<w*h; ++i){*pImageBits = RGB(rand(), rand(), rand());
++pImageBits;}


BITMAPINFO bi;
memset(&bi, 0, sizeof(bi));
bi.bmiHeader.biBitCount=24;
bi.bmiHeader.biHeight=h;
bi.bmiHeader.biPlanes=1;
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bi.bmiHeader.biWidth=w;
bi.bmiHeader.biXPelsPerMeter = 96;
bi.bmiHeader.biYPelsPerMeter = 96;
bi.bmiHeader.biCompression = BI_RGB;
bi.bmiHeader.biSizeImage = w2*h*3;

HDC hdc;
hdc = GetDC(NULL);
HBITMAP hbm = ::CreateDIBitmap(hdc, (BITMAPINFOHEADER*)&bi,
CBM_INIT,
pImageBits, &bi, DIB_RGB_COLORS);
this->CreateIndirect(hbm);
ReleaseDC(NULL, hdc);
delete[] pImageBits;
# # #

The CreateIndirect does:
# # #
Clear();
m_Bitmap = CopyBitmap(CBitmap::FromHandle(hSrcBitmap));
# # #


--
-Gernot
int main(int argc, char** argv) {printf
("%silto%c%cf%cgl%ssic%ccom%c", "ma", 58, 'g', 64, "ba", 46, 10);}

________________________________________
Looking for a good game? Do it yourself!
GLBasic - you can do
www.GLBasic.com


Posted by Alex Fedotov on July 26th, 2006


Gernot Frisch wrote:

Avoid using CreateDIBitmap, use CreateDIBSection instead.

The bitmap created by CreateDIBitmap has the same color depth as the passed
in device context. Since the device context obtained by GetDC initially
contains a 1x1 monochrome bitmap, your code ends up creating a monochrome
bitmap out of the RGB array.

-- Alex Fedotov


Posted by Gernot Frisch on July 26th, 2006



GetDC(NULL) is the desktop window's DC - isn't it?



Posted by Grzegorz Wróbel on July 26th, 2006


Did you initialize the generator?

Gernot Frisch wrote:

--
677265676F727940346E6575726F6E732E636F6D

Posted by Gernot Frisch on July 27th, 2006


What does that mean?



Posted by Grzegorz Wróbel on July 27th, 2006


Gernot Frisch wrote:
Well before using any generator you have to call a function that initialize it. Otherwise you'll get zeros.
So in case of built-in C simple, linear congruency generator, you'll need to call srand() once before calls to rand().
srand(time(NULL));

I think you might have other bug in your loop, but once generator is working you'll discover it yourself.

--
677265676F727940346E6575726F6E732E636F6D

Posted by Alex Fedotov on July 27th, 2006


Gernot Frisch wrote:

You are probably right here, desktop window's DC should be good enough
to set the color format.

-- Alex Fedotov



Posted by Alex Fedotov on July 27th, 2006


Grzegorz Wróbel wrote:

I don't think so. What will happen is that the sequence will be the same for
every run, but it won't be all zeroes either.

-- Alex Fedotov



Posted by Grzegorz Wróbel on July 27th, 2006


Alex Fedotov wrote:
It would be the same only if you initialized the generator with constant value.
I'm not sure how how it is with rand(), but many more advanced generators. if not initialized usually behave like that (they often have few internal parameters that need to be set to proper values). Although formaly you can only say their behaviour is undefined.

--
my website: http://www.4neurons.com/
my email: 677265676F727940346E6575726F6E732E636F6D

Posted by Jerry Coffin on July 28th, 2006


In article <eabdd9$lc0$1@nemesis.news.tpi.pl>,
/dev/null@localhost.localdomain says...

[ ... ]

The C standard requires that if you don't call srand(), rand() will
act as if srand(0) had been called -- i.e. it's initialized, and
returns some pseudo-random stream, but the stream will be the same
every time the code is run.

--
Later,
Jerry.

The universe is a figment of its own imagination.

Posted by Grzegorz Wróbel on July 29th, 2006


Jerry Coffin wrote:
Well, I checked it. If not initialized it behaves as if srand(1) was called.

I took a look once again and I know why Gernot got the black bitmap. His buggy code in the loop:

The loop should be:
for(int i=0;i<w*h*3)
pImageBits[i] = BYTE(rand()%256);

or (worse, because will change the pointer):
for(int i=0;i<w*h*3)
*pImageBits++ = BYTE(rand()%256);



--
my website: http://www.4neurons.com/
my email: 677265676F727940346E6575726F6E732E636F6D

Posted by Jerry Coffin on July 29th, 2006


In article <eaee33$h61$1@nemesis.news.tpi.pl>,
/dev/null@localhost.localdomain says...
Oops -- quite right. Sorry 'bout being off by one like that.

I hadn't looked at that part of the code, but you're certainly
correct -- he was repeatedly writing to the one pixel in the top,
left-hand corner, and never touching any other. From the looks of
things, the rest was being initialized to zeros, so the result was
black pixels...

--
Later,
Jerry.

The universe is a figment of its own imagination.

Posted by Grzegorz Wróbel on July 29th, 2006


Jerry Coffin wrote:

Most likely in bottom-left corner, unless his bitmap was top-down. So it was certainly hard to spot for him this one pixel was red.

--
my website: http://www.4neurons.com/
my email: 677265676F727940346E6575726F6E732E636F6D

Posted by Gernot Frisch on August 1st, 2006



"Grzegorz Wróbel" </dev/null@localhost.localdomain> schrieb im
Newsbeitrag news:eafnsf$jjq$1@atlantis.news.tpi.pl...

Doh! Thank you. There was some other problem as well, but I got it
working now.




Similar Posts