views:

649

answers:

4

Hello

I have an image data in a buffer(type - long) from a scanner which is 32 bit.

For example, buffer[0]'s corresponding pixel value is 952 which is [184, 3, 0, 0] <-[R,G,B,A];

I want to display/Paint/draw on to the screen; I am confused when i tried to read about displying bitmaps. I looked at win32 functions, CBitmap class, windows forms (picture box) etc I am hard to understand the general idea/appraoch for displaying this buffer data on to a application window.

I have constructed the BITMAPFILEHEADER AND BITMAPINFOHEADER; Has the pixel data in a buffer, (unsigned char *)vInBuff whose size is vImageSz;

//construct the BMP file Header
vBmfh.bfType      = 19778;
vBmfh.bfSize      = 54+vImageSz;//size of the whole image
vBmfh.bfReserved2 = 0;
vBmfh.bfReserved1 = 0;
vBmfh.bfOffBits   = 54;//offset from where the pixel data can be found
//Construct the BMP info header
vBmih.biSize        = 40;//size of header from this point
vBmih.biWidth       = 1004;
vBmih.biHeight      = 1002;
vBmih.biPlanes      = 1;
vBmih.biCompression = BI_RGB;
vBmih.biSizeImage   = vBmih.biWidth*vBmih.biHeight*4;
vBmih.biBitCount    = 32;
vBmih.biClrUsed     = 0;
vBmih.biClrUsed     = 0;

1.What is that i should be doing next to display this?

2 What should i be using to display the 32bit bitmap? I see people using createwindows functions, windows forms, MFC etc;

3.I also understand that BitBlt,createDIBSection, OnPaint etc are being used? I am confused by these various functions and coding platforms? Please suggest me a simple approach.

4.How can i create a palette to display a 32 bit image?

Thanks

Raj
EDITED TRYING TO IMPLEMENT DAVE'S APPROACH, CAN SOMEBODY COMMENT ON MY IMPLEMTATION. I couldn't continue to the bitblt as i donot have two HDC, i donot know how to get this one? Any help please

DisplayDataToImageOnScreen(unsigned char* vInBuff, int vImageSz)  // buffer with pixel data, Size of pixel data
{
unsigned char* vImageBuff = NULL;

HDC hdcMem=CreateCompatibleDC(NULL); 

HBITMAP hBitmap = CreateDIBSection(hdcMem, 
                                   (BITMAPINFO*)&vBmih, 
                                   DIB_RGB_COLORS,
                                   (void **)&vImageBuff, 
                                   NULL, 0);

GetDIBits(hdcMem,
          hBitmap,
               0,
               1,
         (void**)&vImageBuff,
         (BITMAPINFO*)&vBmih,
         DIB_RGB_COLORS);

memcpy(vImageBuff,vInBuff,vImageSz);

}
A: 

Here's a strategy you might like:

Create a bitmap with the same size as your scanned data, and the same format (use CreateDIBSection).

Use GetDIBits to get the base address of the pixel data.

Copy your data (from the scanner) to the address GetDIBits returns.

Now render your bitmap! (use BitBlt, or somesuch).

Regarding palettes- a 32bit image does not, generally, have an explicit palette - you'd need 16.7million (assuming 8bits of alpha) values in the palette. Generally the palette is assumed to be 8bits red, 8bits green, 8bits blue, as you've described above.

Dave Gamble
Hello Dave, I have updated my post with your approach. I am unable to proceed further, Can you please break your post in to few more simple steps so that i can follow.ThanksRaj
Raj
You will be given the correct DC to draw with in your OnPaint function.
Dave Gamble
You could invalidate the window in order to force an OnPaint, or as Nick D suggests, use GetDC.
Dave Gamble
+1  A: 

An alternative if you just want to plot it on screen is to use TinyPTC ( http://sourceforge.net/projects/tinyptc/files/ ). It's just 3 functions and very simple if you just want to plot some pixels.

EDIT: Seems like http://www.pixeltoaster.com is a continuation of TinyPTC, probably preffered.

+1 for TinyPTC. Fast, small, and easy to use.
R Ubben
+1  A: 

If you have image's bytes already in a buffer you can use:

a CBitmap object (MFC) and the method CBitmap::CreateBitmapIndirect
or
win32 routine CreateBitmapIndirect.

Now you can use BitBlt to draw it on a DC. To get a window DC use GetDC.

There is no need to create a pallete for 32 bit images.

Nick D
A: 

here's a simplified approach you can try, broken down into steps:

BITMAPINFO bitmapinfo = { 0 };
bitmapinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bitmapinfo.bmiHeader.biWidth = 1004;
bitmapinfo.bmiHeader.biHeight = -1002;
bitmapinfo.bmiHeader.biPlanes = 1;
bitmapinfo.bmiHeader.biCompression = BI_RGB;

HBITMAP hBitmap = CreateDIBSection(NULL, 
                                   &bitmapinfo, 
                                   DIB_RGB_COLORS,
                                   (void **)&vImageBuff,
                                   NULL,
                                   0);

now party on vImageBuff and then cache hBitmap somewhere so that within your wndproc you can then in the WM_PAINT handler:

  1. select hBitmap into temp compatible HDC
  2. call BitBlt(..., SRCCOPY) from the compatible HDC to the window's HDC. the other parameters should be obvious. don't try to stretch or do anything fancy at first.
  3. remember to select the original dummy bitmap into the temp HDC before destroying it.

if you aren't seeing results try looping through vImageBuff and just set every pixel to RGB(255, 0, 0), or something like that, just to sanity check the rest of the logic.

if nothing is drawing make sure that the alpha component for each pixel is 255.

if you're getting a garbled image then you need to double-check pixelformat, stride, etc.

~jewels

Jewel S