Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 595
  • Last Modified:

Show Image on screen from Byte data!!

Hello,
      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.
0
pmukti
Asked:
pmukti
2 Solutions
 
SteHCommented:
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.
0
 
AlexFMCommented:
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.
0
 
pmuktiAuthor Commented:
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 size.so 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.


0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
SteHCommented:
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
0
 
pmuktiAuthor Commented:
I am not getting this point ->what type of bitmap do you use?

May be you are right.here 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 monitor.here 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.
      //_T("C:\\testbmp.bmp"
      hFile = CreateFile(FileName,
                           GENERIC_READ | GENERIC_WRITE,
                           (DWORD) 0,
                              NULL,
                           CREATE_ALWAYS,
                           FILE_ATTRIBUTE_NORMAL,
                           (HANDLE) NULL);
      bmpfHeader.bfReserved1=0;
      bmpfHeader.bfReserved2=0;

      // 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"));
      }

      pbmpInfo=CreateBitmapInfoStruct();

      if (MaxImgByte==1){//this is for 8-Bit image
            for(int i=0;i<=255;i++){
                  pbmpInfo->bmiColors[i].rgbBlue=i;
                  pbmpInfo->bmiColors[i].rgbRed=i;
                  pbmpInfo->bmiColors[i].rgbGreen=i;
                  pbmpInfo->bmiColors[i].rgbReserved=0;
            }
      }
      else{//this is for 16-Bit Image
            pbmpInfo->bmiColors[0].rgbBlue=0;
            pbmpInfo->bmiColors[0].rgbRed=0;
            pbmpInfo->bmiColors[0].rgbGreen=0;
            pbmpInfo->bmiColors[0].rgbReserved=0;
      }
      pbmpInfo->bmiHeader.biXPelsPerMeter=0;
      pbmpInfo->bmiHeader.biYPelsPerMeter=0;
      //pbi->bmiHeader=pbih;  
      // 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"));
            }
      }
      else
      {//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);
      //memcpy(tmp_ptr,imgData,pbmpInfo->bmiHeader.biSizeImage);
      dwtotImgData=pbmpInfo->bmiHeader.biSizeImage;

      //manupulate image data
      //hp=byte_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
                  */
                  gpart=imgData[i+1]&63;
                  rpart=(gpart<<9);
                  bpart=gpart&31;
                  gpart=gpart<<5;
                  
                  /* this is just for trial to make the image gray color but not working!!!
                  gpart=imgData[i+1]&15;
                  rpart=(gpart<<9);
                  bpart=gpart&7;
                  gpart=gpart<<5;
                  */

                  tot16bit=rpart|gpart|bpart;
                  tmp_ptr[(dwtotImgData)-i]=tot16bit&65280>>8;//|bpart|gpart);//&32767;
                  rpart=imgData[i]&31;
                  tmp_ptr[(dwtotImgData)-(i+1)]=tot16bit&255;//|bpart|gpart);//&32767;
                  //img_ptr[i]=img_ptr[i];
                  //newUPart;//|
            }
            memcpy(imgData,tmp_ptr,dwtotImgData);
            free(tmp_ptr);
      }
      
      //Thirdly write ImgData
      if (!WriteFile(hFile, imgData,  dwtotImgData, (LPDWORD) &dwbytret,NULL))
      {
            MessageBox(_T("write image data Error"));
      }

      if(!CloseHandle(hFile)){
            MessageBox(_T("Error in Closing .BMP File"));
      }
      
      //MessageBox(_T("SuccessFully Copy Image File"));
      
}





 
0
 
RJSoftCommented:
SetDIBits

RJ
0
 
DanRollinsCommented:
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
0
 
SteHCommented:
Quote from MSDN:

[quote]
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.  
[/quote]

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.
0
 
migoEXCommented:
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.

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

migoEX
EE Cleanup Volunteer
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now