Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

Display 8bit image data in a window

Posted on 2006-07-21
4
Medium Priority
?
433 Views
Last Modified: 2013-11-20
Hi All,

I need to display some data in the View of an MFC application.

The data i have has come from a camera and is 8 bit data with each bit representing one grey scale pixel value.

I'm having problems display the data at the moment.  With the code i have the image is the correct size but the image within it seems to repeat itself four times.

My current solution involves trying to create a CBitmap object out of the data using CreateCompatibleBitmap and SetBitmapBits.

I have very little experience of palettes and CBitmaps so any help would be appreciated.

This is the code I currently have in OnDraw:  (pImage->GetData returns the raw data)

ImageData* pImage = pDoc->GetImage();

CDC dcMem;
dcMem.CreateCompatibleDC(pDC);

CBitmap bitmap;
bitmap.CreateCompatibleBitmap(pDC, pImage->GetWidth(), pImage->GetHeight());
bitmap.SetBitmapBits(pImage->GetNumberOfBytes(), pImage->GetData());
CBitmap* pOldBitmap = dcMem.SelectObject(&bitmap);
pDC->BitBlt(0, 0, pImage->GetWidth(), pImage->GetHeight(), &dcMem, 0, 0,SRCCOPY);
dcMem.SelectObject(pOldBitmap);

Maybe i need to do something with the palette?

Thanks
0
Comment
Question by:spforeman
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
4 Comments
 
LVL 22

Accepted Solution

by:
mahesh1402 earned 2000 total points
ID: 17152599
It seems you have 8 bit 'Raw' data obtained from camera..I will suggest you to convert this 8-bit data to bitmap using code something like following :

// Allocate bitmap header structure
BITMAPINFO * BMI = (BITMAPINFO*)new unsigned char[sizeof(BITMAPINFOHEADER) + (sizeof(RGBQUAD) * 256)];

// Fill the greyscale palette
for (int GenPal = 0; GenPal < 256; GenPal++)
    *(int*)(&BMI->bmiColors[GenPal]) = GenPal * 0x10101;

// Fill in some information about the image we'll be creating
BMI->bmiHeader.biSize = sizeof(BMI->bmiHeader);
BMI->bmiHeader.biWidth = 128;   // here specify image width
BMI->bmiHeader.biHeight = 128; // here specify image height
BMI->bmiHeader.biPlanes = 1;
BMI->bmiHeader.biBitCount = 8;
BMI->bmiHeader.biCompression = BI_RGB;
BMI->bmiHeader.biXPelsPerMeter = 0;
BMI->bmiHeader.biYPelsPerMeter = 0;
BMI->bmiHeader.biClrUsed = 256;
BMI->bmiHeader.biClrImportant = 256;

// Get the DWord aligned scanline width
int ScanLine = (BMI->bmiHeader.biWidth + 3) & 0xFFFFFFFC;

// Fill in the image data size in the header
BMI->bmiHeader.biSizeImage = ScanLine * BMI->bmiHeader.biHeight;

// Create a New DC
HDC DrawDC = CreateCompatibleDC(NULL);

unsigned char * DataPtr; // <===== This is the pointer to the raw image data

// Create a new DIBSection
HBITMAP DrawBMP = CreateDIBSection(DrawDC, BMI, DIB_RGB_COLORS, (void**)&DataPtr, NULL, NULL);

// Select DIBSection into DC
HBITMAP OldBMP = (HBITMAP)SelectObject(DrawDC, DrawBMP);

if (OldBMP != NULL) { // Write image data (You would just copy your data in here)
    for (int DoY = 0; DoY < BMI->bmiHeader.biHeight; DoY++)
        for (int DoX = 0; DoX < BMI->bmiHeader.biWidth; DoX++)
            DataPtr[(DoY * ScanLine) + DoX] = DoX + DoY;

    // Draw the image to the screen (Assuming "hdc" holds the device context of your viewport)
    BitBlt(hdc, 0, 0, BMI->bmiHeader.biWidth,  BMI->bmiHeader.biHeight, DrawDC, 0, 0, SRCCOPY);

    // De-select DIBSection from the DC
    SelectObject(DrawDC, OldBMP);
 }
 
// Clean up GDI objects
DeleteObject(DrawBMP);
DeleteDC(DrawDC);

// Clean up header structure
delete BMI;

Hope this helps
-MAHESH
0
 
LVL 22

Expert Comment

by:mahesh1402
ID: 17152667
you can also use SetDIBitsToDevice for this purpose

   LPBITMAPINFO bitinfo;
    unsigned char image[ImgHeight][ImgWidth];
    FILE *fp;

    fp = fopen("hands.raw", "rb");  // open raw file.. this is your 8 bit raw file received from camera
    if( fp == NULL ) return;

    bitinfo = (LPBITMAPINFO)new char[sizeof(BITMAPINFO) + 255*sizeof(RGBQUAD)];
    bitinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bitinfo->bmiHeader.biWidth = ImgWidth;
    bitinfo->bmiHeader.biHeight = ImgHeight;
    bitinfo->bmiHeader.biPlanes = 1;
    bitinfo->bmiHeader.biBitCount = 8;                  
    bitinfo->bmiHeader.biCompression = BI_RGB;
    bitinfo->bmiHeader.biSizeImage = 0;
    bitinfo->bmiHeader.biXPelsPerMeter = 0;
    bitinfo->bmiHeader.biYPelsPerMeter = 0;
    bitinfo->bmiHeader.biClrUsed = 256;
    bitinfo->bmiHeader.biClrImportant = 256;

    // gray palette
    for(int i = 0; i < 256; i++)
    {
      bitinfo->bmiColors[i].rgbRed = char(i);
      bitinfo->bmiColors[i].rgbBlue = char(i);
      bitinfo->bmiColors[i].rgbGreen = char(i);
      bitinfo->bmiColors[i].rgbReserved = 0;
    }

    for( int i=0; i<ImgHeight; i++)
    {
        fread( image[i], 1, ImgWidth, fp );
    }

// Create DC goes here

    ::SetDIBitsToDevice( hDC,0,0,ImgWidth,ImgHeight,0,0, 0,ImgHeight,image,bitinfo, DIB_RGB_COLORS);

    fclose( fp );
    delete[] bitinfo;
}
NOTE : If the width of a scanline is not divisible by 4, you must change the code to pad each line.  refer prev src code for ScanLIne calculation

-MAHESH
0
 
LVL 22

Expert Comment

by:mahesh1402
ID: 17153931
othewise if you dont want to go as above simply :

1) Get *.raw filesize [file_size]

2) Create an array unsigned char* lpBits = new unsigned char[file_size];

3) Read the data from the file to lpBits

4) Create CBitmap from this data:
    CBitmap bm;
    bm.CreateBitmap( width, height, 1, 8, lpBits ); // you should know width height of raw image, and bits-per-pixel=8

5) Initialize PictureHolder with this bitmap:
    CPictureHolder::CreateFromBitmap((HBITMAP)bm);

6) Display bitmap:
    CPictureHolder::Render(...);

7) Clean up:
    delete [] lpBits;

-MAHESH
0
 

Author Comment

by:spforeman
ID: 17154490
Thanks for the help MAHESH

All three solutions were spot on.

I had spent a day trying to do this and was so close.
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

If you use Adobe Reader X it is possible you can't open OLE PDF documents in the standard. The reason is the 'save box mode' in adobe reader X. Many people think the protected Mode of adobe reader x is only to stop the write access. But this fe…
In this post we will learn different types of Android Layout and some basics of an Android App.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Please read the paragraph below before following the instructions in the video — there are important caveats in the paragraph that I did not mention in the video. If your PaperPort 12 or PaperPort 14 is failing to start, or crashing, or hanging, …
Suggested Courses

650 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question