Newbie Image Help
-
Hi, I have a string of RGB RGB RGB RGB bytes that makes up a image, and I'd like to display it onto the screen. Can someone please give me the road map for doing that? It's kinda confusing for someone w/ minium graphical background. Here's what I wanted to do: 1. Put the RGBRGBRGBRGB string into a CBitmap 2. Display the CBitmap onto my screenDC (where screen may have any color bit depth -32bit 24bits 16bits...) My CBitmap image only displays properly when my monitor is set to 32bit/pixel. I believe I need to use DIB for these various bit depth compatability. THANKS IN ADVANCE! :-D
-
Hi, I have a string of RGB RGB RGB RGB bytes that makes up a image, and I'd like to display it onto the screen. Can someone please give me the road map for doing that? It's kinda confusing for someone w/ minium graphical background. Here's what I wanted to do: 1. Put the RGBRGBRGBRGB string into a CBitmap 2. Display the CBitmap onto my screenDC (where screen may have any color bit depth -32bit 24bits 16bits...) My CBitmap image only displays properly when my monitor is set to 32bit/pixel. I believe I need to use DIB for these various bit depth compatability. THANKS IN ADVANCE! :-D
Yes, to get an image that will display on any screen, you need a DIBSECTION. There are some good DIBSECTION wrappers on this site. The good thing is having created on, you get a pointer to the image data, and can just move your byte array into it. There's a catch though - Windows stores images a BGR, not RGB. If indeed you have RGB ( not BGR ), you'll need to swap some values as you copy them in, otherwise memset will be fine. If the wrapper you use does not have a draw method, you can just create a DC and select your image into it. CDC memDC; memDC.CreateCompatibleDC(NULL); memDC.SelectObect(name of your image, dereferenced if it's a pointer, assuming it offers operator HBITMAP); then you can just BitBlt it onto the screen. Christian After all, there's nothing wrong with an elite as long as I'm allowed to be part of it!! - Mike Burston Oct 23, 2001
Sonork ID 100.10002:MeanManOz
I live in Bob's HungOut now
-
Hi, I have a string of RGB RGB RGB RGB bytes that makes up a image, and I'd like to display it onto the screen. Can someone please give me the road map for doing that? It's kinda confusing for someone w/ minium graphical background. Here's what I wanted to do: 1. Put the RGBRGBRGBRGB string into a CBitmap 2. Display the CBitmap onto my screenDC (where screen may have any color bit depth -32bit 24bits 16bits...) My CBitmap image only displays properly when my monitor is set to 32bit/pixel. I believe I need to use DIB for these various bit depth compatability. THANKS IN ADVANCE! :-D
Christian has already answered your question in an authoritative fashion, but I'd like to point out two more catches (apart from the BGR order) you should be aware of:
-
There's a padding issue, namely that all bitmap rows must occupy a number of bytes that is multiple of 4. For instance, if your image is 5 pixels wide, then the bitmap is stored as
/----row 1-----\/----row 2-----\/----row 3-----\
BGRBGRBGRBGRBGRXBGRBGRBGRBGRBGRXBGRBGRBGRBGRBGRX...Where the X is one padding byte that makes every row occupy 16 bytes (the value of this byte is irrelevant).
-
The first row stored is at the bottom, and the last one at the top. The usual assumption is the other way around, but the MS guys decided on this order for some strange reason.
Joaquín M López Muñoz Telefónica, Investigación y Desarrollo
-
-
Yes, to get an image that will display on any screen, you need a DIBSECTION. There are some good DIBSECTION wrappers on this site. The good thing is having created on, you get a pointer to the image data, and can just move your byte array into it. There's a catch though - Windows stores images a BGR, not RGB. If indeed you have RGB ( not BGR ), you'll need to swap some values as you copy them in, otherwise memset will be fine. If the wrapper you use does not have a draw method, you can just create a DC and select your image into it. CDC memDC; memDC.CreateCompatibleDC(NULL); memDC.SelectObect(name of your image, dereferenced if it's a pointer, assuming it offers operator HBITMAP); then you can just BitBlt it onto the screen. Christian After all, there's nothing wrong with an elite as long as I'm allowed to be part of it!! - Mike Burston Oct 23, 2001
Sonork ID 100.10002:MeanManOz
I live in Bob's HungOut now
Thank you Christian for the tip. I found a DIBSection wrapper in Code Project, but the image still does not display properly with 16-bit color depth monitor setting. I think it's because I am creating a bitmap wrong. Can you please take a look at the following: *imageBuffer points to my image array BGRxBGRxBGRx...
bitmapBefore.CreateBitmap(sizeBefore.cx, sizeBefore.cy, 1, 32, imageBuffer);
And then I display the bitmapBefore in my view. This is what I did before in view:CBitmap *bitmap = &(pDoc->bitmapBefore); dcTemp.CreateCompatibleDC(&cDC); dcTemp.SelectObject(bitmap); cDC.BitBlt(0,0, pDoc->sizeAfter.cx, pDoc->sizeBefore.cy, &dcTemp, 0, 0, SRCCOPY);
and this is what I changed w/ DIBSection wrapper:CBitmap *bitmap = &(pDoc->bitmapBefore); CDIBSectionLite dibsection; dibsection.SetBitmap(*bitmap); dibsection.Draw(&cDC, CPoint(0,0));
They give the same results... Whenever I set my screen color depth to anything other than True Color (32bit), I get white surface. Can you spot what I'm doing wrong? Thanks for your help! Jerry -
Christian has already answered your question in an authoritative fashion, but I'd like to point out two more catches (apart from the BGR order) you should be aware of:
-
There's a padding issue, namely that all bitmap rows must occupy a number of bytes that is multiple of 4. For instance, if your image is 5 pixels wide, then the bitmap is stored as
/----row 1-----\/----row 2-----\/----row 3-----\
BGRBGRBGRBGRBGRXBGRBGRBGRBGRBGRXBGRBGRBGRBGRBGRX...Where the X is one padding byte that makes every row occupy 16 bytes (the value of this byte is irrelevant).
-
The first row stored is at the bottom, and the last one at the top. The usual assumption is the other way around, but the MS guys decided on this order for some strange reason.
Joaquín M López Muñoz Telefónica, Investigación y Desarrollo
Really? I'm a bit confused... I experimented w/ byte ordering RGB values in my CBitmap, and it came out to be BGRxBGRxBGRx... which displayed properly in a 32-bit color depth monitor setting. So, that must be what's wrong w/ my code then? I should create BGRBGRBGRBGRX... and how should I create this DIB? Is DIB a sub-catagory of CBitmap? Also, since CreateDIBSection asks for pDC, how can I create an DIB image when I don't have a DC that goes with it... or can I? Thanks man!
-
-
Thank you Christian for the tip. I found a DIBSection wrapper in Code Project, but the image still does not display properly with 16-bit color depth monitor setting. I think it's because I am creating a bitmap wrong. Can you please take a look at the following: *imageBuffer points to my image array BGRxBGRxBGRx...
bitmapBefore.CreateBitmap(sizeBefore.cx, sizeBefore.cy, 1, 32, imageBuffer);
And then I display the bitmapBefore in my view. This is what I did before in view:CBitmap *bitmap = &(pDoc->bitmapBefore); dcTemp.CreateCompatibleDC(&cDC); dcTemp.SelectObject(bitmap); cDC.BitBlt(0,0, pDoc->sizeAfter.cx, pDoc->sizeBefore.cy, &dcTemp, 0, 0, SRCCOPY);
and this is what I changed w/ DIBSection wrapper:CBitmap *bitmap = &(pDoc->bitmapBefore); CDIBSectionLite dibsection; dibsection.SetBitmap(*bitmap); dibsection.Draw(&cDC, CPoint(0,0));
They give the same results... Whenever I set my screen color depth to anything other than True Color (32bit), I get white surface. Can you spot what I'm doing wrong? Thanks for your help! JerryHaving looked at the DIBSectionLite code, the draw function works one of two ways, depending on if hDrawDib is defined ( not NULL ). I don't know anything about DibDrawDib, but if you comment out lines 636-649 of DibSectionLite, it will then act the way I was anticipating, and I see no reason for you to have any worries. Christian After all, there's nothing wrong with an elite as long as I'm allowed to be part of it!! - Mike Burston Oct 23, 2001
Sonork ID 100.10002:MeanManOz
I live in Bob's HungOut now
-
Really? I'm a bit confused... I experimented w/ byte ordering RGB values in my CBitmap, and it came out to be BGRxBGRxBGRx... which displayed properly in a 32-bit color depth monitor setting. So, that must be what's wrong w/ my code then? I should create BGRBGRBGRBGRX... and how should I create this DIB? Is DIB a sub-catagory of CBitmap? Also, since CreateDIBSection asks for pDC, how can I create an DIB image when I don't have a DC that goes with it... or can I? Thanks man!
Yes, the bottom to top ordering and the BGR ordering are standard in windows, so if the image is coming in that way, then it's fine. CBitmap is a DDB - a device dependant bitmap. A DIB is device INdependant, in other words it defines it's own colour depth instead of relying on the colour depth of a device. A DIB cannot be used to draw on, etc. using a CDC. A DIBSection is a hybrid creature - a DIB that has a HBITMAP which can be selected into a DC and used like any other HBITMAP ( which CBitmap is an extended wrapper for ). CreateDIBSection can just be passed in a CDC created with CreateCompatibleDC(NULL); The code I pointed you to on the WDJ site does this. Christian After all, there's nothing wrong with an elite as long as I'm allowed to be part of it!! - Mike Burston Oct 23, 2001
Sonork ID 100.10002:MeanManOz
I live in Bob's HungOut now
-
Yes, the bottom to top ordering and the BGR ordering are standard in windows, so if the image is coming in that way, then it's fine. CBitmap is a DDB - a device dependant bitmap. A DIB is device INdependant, in other words it defines it's own colour depth instead of relying on the colour depth of a device. A DIB cannot be used to draw on, etc. using a CDC. A DIBSection is a hybrid creature - a DIB that has a HBITMAP which can be selected into a DC and used like any other HBITMAP ( which CBitmap is an extended wrapper for ). CreateDIBSection can just be passed in a CDC created with CreateCompatibleDC(NULL); The code I pointed you to on the WDJ site does this. Christian After all, there's nothing wrong with an elite as long as I'm allowed to be part of it!! - Mike Burston Oct 23, 2001
Sonork ID 100.10002:MeanManOz
I live in Bob's HungOut now
Thanks Christian for the explaination. Thanks Jouquin for your help also. PJ Arends sent me a really helpful section of the code using CreateDIBSection and SetDIBits. Just like you said. I am able to display images in different bit depths now :) Thanks so much.