Show Image on screen from Byte data!!

Posted on 2003-12-02
Last Modified: 2007-12-19
      I have image data in byte stream format.Now i don't know how to show them on screen or window?I had tried it to first convert it into bitmap format.but i don't want to do like this way.Is there any other way to show them on window without loosing any color information.It is 16-bit and 8- bit type image data.For any type of format it is welcome.
I just want the way.Does any body show me the correct path??I will be really very greateful to you...
  I am making MFC Dialog base application.
Question by:pmukti
LVL 13

Accepted Solution

SteH earned 125 total points
ID: 9857406
Could you tell us why you don't want to convert the data to a bitmap first? Showing a bitmap, or another image format, has the advantage that redrawing is done automatically when the window was hidden and comes back to front.

Did you have problems with loosing color information? This sounds more like the screen color depth is not suited for the color information of the data you got.
LVL 48

Expert Comment

ID: 9858051
Check out MFC FIRE sample. This sample shows 8 bpp palette image on the screen. Image is generated as memory array and drawn on the screen using device-independent bitmap (DIB).
If you need to show monochrome 8 bits per pixels image, use monocrome palette: (0, 0, 0) ... (255, 255, 255).
The only way to show 16 bpp grayscale images in Windows is converting them to 8 bpp. This may be done by simple way (using only high 8 bits of each pixel) or applying some optimization. For example, if 16 bpp image contains pixels in interval from 3000 to 4000, only this interval may be mapped to 0-255 interval.

Author Comment

ID: 9866164
Thanx for your interest.

I have no problem to convert the data into bitmap but the color information should not be lose. The way i do is first i put one by one pixel color information from buffer to device context by setpixel method.which will slow down the process for large file do u have any otherway to show the image data on device context?

I had seen the MFC Fire sample.but in that i am not getting from where it is taking the image data color information.
whether it is taking from palette array or from image buffer.Do you have any other simple example by that i can know it better.

LVL 13

Expert Comment

ID: 9866272
Why do you think to loose color information? What type of bitmap do you use?

A poblem could be the mapping of colors from your data (file/DIB/etc) to display. To display 8bit greyscale images you need at least 24 bits color depth for the display. All 3 colors are identical so 8 bit would be sufficient but when the graphics card uses a 16 bit color depth you have 5/6/5 bits per color. And that is not sufficient for displaying your data. So I guess your color information is lost only during displaying. It will stay correct in the bitmap/DIB but can't be displayed correctly.

But to give better help you need to tell us the color depth setting of the display and the type of image data. 8bit could be 256 colors or 256 greyscales. And a snippet of code could be very helpful as well.

And for 16bit greyscales
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.


Author Comment

ID: 9872575
I am not getting this point ->what type of bitmap do you use?

May be you are I tell you my actual problem.I have one camera source which give me 8 bit grayscale buffer and unfortunetaly 14-bit gray scale buffer.when i get 8 bit grayscale buffer.i can handle it and display it succesfully on the screen. but when the case come with 14-bit i am not able to display it in correct manner.even i am not able to make succesfull bmp from that data buffer.I had tried by many ways but not succeeded in this.i had search many topics on net about 16 bit grayscale bitmap information.but not get proper information.even i am not sure about whether i had made the perfact bmp file from data buffer and only problem is in displaying it on screen which is due to color depth of card or i am providing you as much i am knowing.i am using normal 17'' IBM monitor and used graphics card modal number is ASUS V9280 S2 super fast 600 Mhz.I am not sure whether it is supperting colordepth of 16  bit.
              if you know much detail about all these please explain it breifly to me.I am a simple programmer and i don't have more knowledge on this.if you have some good link on these.give it to me.I want to know more about this.

CCDiaImage::WriteBMP(BYTE *imgData, CString FileName)

      HANDLE hFile;
      BITMAPFILEHEADER bmpfHeader;
      PBITMAPINFO pbmpInfo;  
      DWORD dwtotImgData;

      // Create the .BMP file.
      hFile = CreateFile(FileName,
                           GENERIC_READ | GENERIC_WRITE,
                           (DWORD) 0,
                           (HANDLE) NULL);

      // Compute the offset to the array of color indices.
      if(MaxImgByte==1){//this is for 8-bit image
            bmpfHeader.bfOffBits =(DWORD) (sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)+(256*sizeof(RGBQUAD)) );
      else{//this is for 16-bit image
            bmpfHeader.bfOffBits =(DWORD) (sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER));
      bmpfHeader.bfType=0x4d42;       // 0x42 = "B" 0x4d = "M"

      // Compute the size of the entire file.
      //pbih->biSizeImage =imageWidth*imageHeight*(BitsPerPixel/8)
      bmpfHeader.bfSize = (DWORD) ((512*512*MaxImgByte)+ bmpfHeader.bfOffBits);

      //first write BMPFILEHEADER
      // Copy the BITMAPFILEHEADER into the .BMP file.
      DWORD dwbytret;

      if (!WriteFile(hFile,(LPVOID) &bmpfHeader,sizeof(BITMAPFILEHEADER),(LPDWORD) &dwbytret,  NULL))
            MessageBox(_T("Can't write BMPFileHeader into File"));


      if (MaxImgByte==1){//this is for 8-Bit image
            for(int i=0;i<=255;i++){
      else{//this is for 16-Bit Image
      // Copy the BITMAPINFOHEADER and RGBQUAD array into the file.
      //secondly write BMPINFOHEADER
      if (MaxImgByte==1){//this is for 8-Bit image
            if (!WriteFile(hFile, (LPVOID) pbmpInfo, sizeof(BITMAPINFOHEADER) +(256*sizeof(RGBQUAD)) ,
                                (LPDWORD) &dwbytret, ( NULL)))
                  MessageBox(_T("error in writing BMP fileinformation Header"));
      {//this is for 16-Bit Image
            if (!WriteFile(hFile, (LPVOID) pbmpInfo, sizeof(BITMAPINFOHEADER) + sizeof(BITMAPFILEHEADER) ,
                                (LPDWORD) &dwbytret, ( NULL)))
                  MessageBox(_T("error in writing BMP fileinformation Header"));
      //BYTE *tmp_ptr=(BYTE *)malloc(pbmpInfo->bmiHeader.biSizeImage);

      //manupulate image data
      if(MaxImgByte!=1){ //i.e 16-Bit BMP file
            BYTE *tmp_ptr=(BYTE *)malloc(dwtotImgData);
            short rpart,gpart,bpart;
            short tot16bit;
            for(int i=dwtotImgData-2;i>0;i-=2){
                  /*this i have done it for all the 6 bit
                  so i am getting white color instead of gray color
                  /* this is just for trial to make the image gray color but not working!!!

      //Thirdly write ImgData
      if (!WriteFile(hFile, imgData,  dwtotImgData, (LPDWORD) &dwbytret,NULL))
            MessageBox(_T("write image data Error"));

            MessageBox(_T("Error in Closing .BMP File"));
      //MessageBox(_T("SuccessFully Copy Image File"));


Expert Comment

ID: 9874980

LVL 49

Assisted Solution

DanRollins earned 125 total points
ID: 9879286
I have never heard of a 14-bit grayscale image.  Do you have any documentation about this?

If each 14-bit value is a simple intensity level, then maybe it can be converted to a 8-bit value without losing much information.  To do that, take each 14-bit value and shift it right by 6 and then pretend that you got an 8-bit value.

But if the grayscale values are palette indexes, then there is much work to do.  Does the image data provide a palette that contains about 16,000 entries?

Anyway, the first step would be to try treating the values as 8-bit grayscale.  Here is how I would do this:

1) Add a STATIC control to the dialog.  Set its ID to IDST_MyPicture and type to "Bitmap"
2) Press Ctrl+W and in the Variables tabl, select IDST_MyPicture
3) Click [Add variable] and set Name to "m_ctlMyPicture" and  Category to "Control"

Now in your program, if you have an HBITMAP you can quickly an easily display it by using:
     m_ctlMyPicture.SetBitmap( hbmp );

So all that is left to do is create the HBITMAP.  As a first step, use code like this:

void CD19Dlg::OnButton1()
      int nWide= 100;
      int nHigh= 100;
      HDC     hdcWnd=  ::GetWindowDC( m_hWnd );
      HBITMAP hbmDest= ::CreateCompatibleBitmap( hdcWnd, nWide, nHigh );
      HDC     hdcMem=  ::CreateCompatibleDC( hdcWnd );   // match screen settings
      // testing: here's how to load a bitmap from a resource
      // HINSTANCE hInst = AfxGetInstanceHandle();
      // hbmDest= LoadBitmap(hInst, MAKEINTRESOURCE(IDBM_Test) );
      HBITMAP hbmOld=  (HBITMAP)SelectObject ( hdcMem, hbmDest ); // will draw on hbmDest

      for (int y=0; y<nHigh; y++ ) {
            for (int x=0; x<nWide; x++ ) {
                  UINT nValueFromGrayScaleArray= 0x2F21; // whatever??? get a 14-bit value
                  UINT nLevel= nValueFromGrayScaleArray >> 6; // discard lo bits of level
                  ::SetPixel( hdcMem, x,y, RGB(nLevel,nLevel,nLevel ) );
      SelectObject( hdcMem, hbmOld ); // put the old bmp back before cleanup

      ::ReleaseDC( m_hWnd, hdcWnd );
      ::DeleteDC( hdcMem );

      m_ctlMyPicture.SetBitmap( hbmDest );  // display the bitmap in the static control

In the above code, I could not show how to process the 14-bit pixel stream... I just set all pixels to the same value.  You will need to get the grayscale image data, one pixel at a time and use SetPixel as shown.

When you get that that, I can show you how to speed it up by placing pixel data directly into a DIBSection.

-- Dan
LVL 13

Expert Comment

ID: 9881257
Quote from MSDN:

16 The bitmap has a maximum of 2^16 colors. If the biCompression member of the BITMAPINFOHEADER is BI_RGB, the bmiColors member is NULL. Each WORD in the bitmap array represents a single pixel. The relative intensities of red, green, and blue are represented with 5 bits for each color component. The value for blue is in the least significant 5 bits, followed by 5 bits each for green and red. The most significant bit is not used. The bmiColors color table is used for optimizing colors used on palette-based devices, and must contain the number of entries specified by the biClrUsed member of the BITMAPINFOHEADER.  

So this assumes a 16 bit COLOR image. You have 14bit grayscale. Thus it will appear completly different after loading since for a 16 bit image windows uses bits 0-4 for blue, 5-9 for green and 10-14 for red. Which is not the case for you. Some programs support 16bit grayscales. Perhaps you can decipher how this changes the header when writing to file.

If you use the 16bit bitmap as defined you only have 5 bits left since all colors are the same. This leaves you with less resolution than a 8 bit grayscale image.

If you use it in your own way be sure to remember it is your very own format windows won't handle correctly for you.

Andnow comes the problem for displaying. A 24bit color depth of the monitor allows to show 8bit grayscales and not more. The rest can be used internally for image analysis but won't be displayed anyhow. Perhaps you make your choice whether you really need the 14bit mode at all.

Expert Comment

ID: 10331467
No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area that this question is:

Split between SteH and DanRollins.

Please leave any comments here within the next four days.


EE Cleanup Volunteer

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
Unlike C#, C++ doesn't have native support for sealing classes (so they cannot be sub-classed). At the cost of a virtual base class pointer it is possible to implement a pseudo sealing mechanism The trick is to virtually inherit from a base class…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

920 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

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now