Link to home
Create AccountLog in
C++

C++

--

Questions

--

Followers

Top Experts

Avatar of Develprog
Develprog

How Display bitmap data (a variable, not a file) into a Picture Box with MFC or WIN32 ?
Hello,
Here is my first post, so I made an application using HBITMAP with the LoadImage method () on a bmp file. But this time I would load an image, not from a file (code below) but using data in memory (see comments).

My program works like a wrapper class by calling a main class named Camdev , this class saves a bitmap file on disk -and my application used HBITMAP LoadImage() to display each image from the camera in the Picture box.
I used the code bellow and that works perfect.

But the Camdev class also has a method that saves in memory (SaveToMem ()). I don't want to save the file on disk, so I 'll save the bitmap in a memory buffer then how do it I heard about using LoadImage with parameter LR_CREATEDIBSECTION but how implement that ?

The MFC LoadBitmap() function does only load bitmaps from resource in VC++ so I decided to use LoadImage() but I don't know how?

How do I pass the bitmap data buffer so my fonctions GetcaptureImage () and DisplayImage () use this data properly with MFC or Win API methods ?



Thank you


Here's the code:
//Capture Image from file (loadimage)
//
#include "stdafx.h"
 
#include "Cam_conf.h"
#include "Cam_confDlg.h"
 
 
HWND hwnd   = NULL;
 
Camdev cp;  //class
 
HBITMAP eventsavedlgdc = (HBITMAP)::LoadImage(NULL,"readframes01.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
HDC           hMemDC;
RECT rectScaled;
int rectW;
int rectH;
 
 
 
 
void CAboutDlg::OnPaint()
{
   CPaintDC dc(this); // device context for painting
 
   CRect rc( 0, 0, 4, 8 );
 
   MapDialogRect( &rc );
   int baseUnitY = rc.bottom;
   int baseUnitX = rc.right;
   TRACE("baseUnitX = %d\n", baseUnitX);
   TRACE("baseUnitY = %d\n", baseUnitY);
   TRACE("Dans OnPaint\n"); //ajout
}
 
 
CCam_confDlg::~CCam_confDlg() //
{
 
	if (m_Picture)::DeleteObject(m_Picture);
	if (Bmp4.m_hObject)::DeleteObject(Bmp4.m_hObject);
	m_Font.DeleteObject();
	cp.StopCapture();
	cp.SaveSettingsToFile();// 
 
}
 
 
BOOL CCam_confDlg::OnInitDialog()
{
	//Set the icon for this dialog.  The framework does this automatically
	//when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);	//Set big icon
	SetIcon(m_hIcon, FALSE);//Set small icon
 
	//dimensions of the control
	m_Picture.GetWindowRect(&rectScaled);
	rectW=rectScaled.right-rectScaled.left;
	rectH=rectScaled.bottom-rectScaled.top;
	
	store=cp.Init(Gl_ip);  // utiliser l'addresse IP de l'argument
	
	SetTimer(ID_TIMER1, 90, 0);				
}
 
void CCam_confDlg::OnTimer(UINT nIDEvent) 
{
		
	CDialog::OnTimer(nIDEvent);
 
	     if (nIDEvent ==ID_TIMER1) 
		{
			TRACE("ON_TIMER_IN\n");
			UpdateData(TRUE);
 
			//KillTimer(1);
			KillTimer(ID_TIMER1);
	
			//MUTEX			
			if(!GetCaptureImage())
			{
				cm_display.Lock();	//Mutex
				if(!DisplayImage())	;				
				cm_display.Unlock();//Mutex	
			}
			SetTimer(ID_TIMER1,10,0);	
			UpdateData(FALSE);
		}		
}
 
 
			
bool CCam_confDlg::GetCaptureImage()
{
	if(!cp.GetCaptureInfo(&status, &newestframeix, &newesttimems,
						&nframes, &nprocbufs, &nusable, &nlocked, lockitems, &nlockitems))
				{	
					gx_geterror(&ecode, ebuf, sizeof(ebuf));
					return TRUE;
				}
				
	// Lock frame
	if(!cp.LockFrames(FXCAM_LOCK_RELEASE_ALL_OTHER, frame, frame)) 
	{  
		// Error occurred
		return TRUE;
	}
	
	// Read frame
	if(!cp.ReadFrame(FXCAM_READFRAME_AUTOADJUST, 0, frame, NULL, &frametimems, &newestframeix, NULL, cp.image)) 
			{
				if(nlockitems == 0) 
				{
				// Error occurred
				return TRUE;
				}
			}
			
	// Release the locked frame
	if(!cp.UnlockFrames(0, frame, frame)) 
			{
				// Error occurred
				return TRUE;
			}
		
	//save image		 //Utiliser SavetoMem vers ppm (pour stream),  vers jpg (pour snapshot)
	if(!cp.image.Save("readframes01.bmp", GX_BMP)) 
	{
		gx_geterror(&ecode, ebuf, sizeof(ebuf));
		return TRUE;
	}
	
	capture_ok=true;
	return FALSE;
}
 
bool CCam_confDlg::DisplayImage() 
{
	  capture_ok=false;	
 
	  if (eventsavedlgdc)
	  { 
	    	::DeleteObject(eventsavedlgdc);
	  }
 
	eventsavedlgdc = (HBITMAP)::LoadImage(NULL,"readframes01.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);//OK
 
	  CBitmap bmp;
	  bmp.Attach(eventsavedlgdc);
	  BITMAP bm;
	  bmp.GetBitmap(&bm);  
	  bmp.Detach(); 
 
	  HDC hdc=::GetDC(m_Picture.m_hWnd);
	  HDC memdc=::CreateCompatibleDC(hdc);
	  HBITMAP hBmp2=(HBITMAP)SelectObject(memdc,eventsavedlgdc);
  
 
	  SetStretchBltMode(hdc,COLORONCOLOR);  //For better quality
      StretchBlt(hdc,0,0,rectW,rectH,memdc,0,0,752,480,SRCCOPY); 
 
      DeleteDC(hdc);
      DeleteDC(memdc);
 
	  if(eventsavedlgdc)
	  {
			m_Picture.SetBitmap(hBmp2);
			DeleteDC(hMemDC);
			DeleteObject(eventsavedlgdc);
	  }
 
	  capture_ok=true;
	  return FALSE;
}

Open in new window

Zero AI Policy

We believe in human intelligence. Our moderation policy strictly prohibits the use of LLM content in our Q&A threads.


Avatar of DevelprogDevelprog

ASKER

Hi,

So I want to know how can I do for loading a bitmap in a picture box.
I can not use a file so I must load the bitmap memory's data ( char* or void* )
So maybe use the LoadImage() function without the parameter LR_LOADFROMFILE  but with LR_DIBSECTION for example is it right and how do it?

Thank you


Avatar of pgnatyukpgnatyuk🇮🇱


If you have MFC, why you don't want to use CBitmap class?
http://msdn.microsoft.com/en-us/library/af93221e(VS.80).aspx
It has te loading method. But you can use your code:
HBITMAP hBitmap = (HBITMAP)LoadImage(NULL, szFilename, IMAGE_BITMAP, 0, 0,
LR_LOADFROMFILE | LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
CBitmap bm;
bm.Attach(hBitmap);
 
You can save it:
bm.Save(_T("C:\\test.bmp"), Gdiplus::ImageFormatBMP);

Hi Develprog,
                       Are you want to save an image to memory or you want to save it to a picture box
Regards,
Vimal

Reward 1Reward 2Reward 3Reward 4Reward 5Reward 6

EARN REWARDS FOR ASKING, ANSWERING, AND MORE.

Earn free swag for participating on the platform.


Avatar of pgnatyukpgnatyuk🇮🇱

If you want to know about the DIBSection...
The attached code creates a dib section.
Actually you can obtain the bit array with GetDiBits api. There is another function - GetBitmapBits:
http://www.codeproject.com/KB/graphics/using_get_set_bitmapbits.aspx
If you want more operations with the image, take a look here (CxImage):
http://www.codeproject.com/KB/graphics/cximage.aspx
BTW, in this library you will find a lot of code and you'll many examples of work with the DIBSection.
You can check CDibSectionLite also:
http://www.codeproject.com/KB/graphics/dibsection.aspx
http://www.codeguru.com/cpp/g-m/bitmap/article.php/c1737

 

    int h = 256
    int w = 256;
 
    BITMAPINFO bmi;
    bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bmi.bmiHeader.biHeight = - h;
    bmi.bmiHeader.biWidth =  w;
    bmi.bmiHeader.biPlanes = 1;
    bmi.bmiHeader.biBitCount = 24;
    bmi.bmiHeader.biCompression = BI_RGB;
    bmi.bmiHeader.biSizeImage = bmi.bmiHeader.biHeight * bmi.bmiHeader.biWidth * 4;
    
    HDC hdc2 = CreateCompatibleDC(NULL);
 
    VOID *pvbits;
 
    HBITMAP hbitmap = CreateDIBSection(NULL,&bmi,DIB_RGB_COLORS,&pvbits,NULL,0x0);
  

Open in new window


Avatar of pgnatyukpgnatyuk🇮🇱

And about the picture box:
CBitmap* theBitmap = new CBitmap();
theBitmap->LoadBitmap(IDB_PICTURE1);
m_myStatic.SetBitmap((HBITMAP)theBitmap);
m_myStatic->Invalidate();
m_myStatic->UpdateWindow();
This code is from http://www.experts-exchange.com/Programming/System/Windows__Programming/MFC/Q_10234007.html

 

Hi,

Thank you all.

Vimamalex my goal is that till now I used function1 and the main loop of my program was to save on disk a file and read (load) the file, see code below :

cp.image.Save("readframes01.bmp", GX_BMP)) //function_1
eventsavedlgdc = (HBITMAP)::LoadImage(NULL,"readframes01.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);  


The class Camdev has 2 functions to save data. Now I must use function2 because
of avoid using a file on disk, see code below:

cp.image.SaveToMem(&Gl_buffer, &Gl_buflen, GX_BMP);  //function_2

But I don't know how to read the bmp data from memory.
So at your question I will say to yes for both. Because my main loop must do that:  saving bmp on memory and reading back to save it in picture control.

The function that save on memory is already done by the Camdev class function_2 so for the moment all I need is to have an MFC or WinAPI function to load bmp data from memory and then a fcuntion to put this bmp data on the picture control.

Pgnatyuk, I use MFC but I combined LoadImage function with an attach like you suggest.  
But it seems to me that a CBitmap object has no a Save method isn' it ?

CBitmap bm;
bm.Save(_T("C:\\test.bmp"), Gdiplus::ImageFormatBMP);  // ?

So maybe there is a function to save on memory and then reload from memory ?

Thank you  

Free T-shirt

Get a FREE t-shirt when you ask your first question.

We believe in human intelligence. Our moderation policy strictly prohibits the use of LLM content in our Q&A threads.


Avatar of pgnatyukpgnatyuk🇮🇱

I hope I understand now. Almost. :)
I showed this code:
HBITMAP hbitmap = CreateDIBSection(NULL,&bmi,DIB_RGB_COLORS,&pvbits,NULL,0x0);
pvbits is the bit array, here are all pixels from your image. Each pixel is RGB - 1 byte per color.
You can save it in the memory, draw primitives yourself, ..., many other things without such functions as LineTo, Rectange, etc.
If you have HBITMAP, you can obtain pointer to this bit array by using GetDIBits:
http://msdn.microsoft.com/en-us/library/dd144879(VS.85).aspx
You understand that there is also SetDIBits function. So you have full access to the each color of each pixel in your image. You can save it in the memory as you want - now it is just an array of bytes for you.
Please take a look here:
http://www.differentpla.net/content/2004/04/direct-access-to-a-bitmap-using-getdibits-and-setdibits
And I've told, try to understand the source code of CxImage and CDibSectionLite.

Avatar of pgnatyukpgnatyuk🇮🇱

>>But it seems to me that a CBitmap object has no a Save method isn' it ?
I attached a sample. You can test.
#include <atlimage.h>
#include <Gdiplusimaging.h>
//bitmap below is CBitmap
CImage image;
image.Attach(bitmap);
image.Save(_T("C:\\test.bmp"), Gdiplus::ImageFormatBMP);

Open in new window


Avatar of pgnatyukpgnatyuk🇮🇱

If you will check this link below you'll find how to save a bitmap in a disk BMP-file:
http://msdn.microsoft.com/en-us/library/dd145119(VS.85).aspx
 

Reward 1Reward 2Reward 3Reward 4Reward 5Reward 6

EARN REWARDS FOR ASKING, ANSWERING, AND MORE.

Earn free swag for participating on the platform.


Hi pqnatyuk,

Thank you for your response.  Sorry I think that I don't explain very well the goal. I'm lucky to say that my Camdev class has already a function that writes on memory so for the moment the real need is to make a function that will be read from memory this bmp data.

In fact I don't need a function that will write on disk because the funtion_1 from class Camdev do that:

cp.image.Save("readframes01.bmp", GX_BMP)) //function_1


For the moment the important goal is to make a function that will load bmp data from memory and display it on a Picture control .

My old displaying function (when loading from file) was  (see code):


How must I change this displaying function to obtain the goal?

Thank you

bool CCam_confDlg::DisplayImage() 
{
	  capture_ok=false;	
 
	  if (eventsavedlgdc)
	  { 
	    	::DeleteObject(eventsavedlgdc);
	  }
 
	eventsavedlgdc = (HBITMAP)::LoadImage(NULL,"readframes01.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);//OK
 
	  CBitmap bmp;
	  bmp.Attach(eventsavedlgdc);
	  BITMAP bm;
	  bmp.GetBitmap(&bm);  
	  bmp.Detach(); 
 
	  HDC hdc=::GetDC(m_Picture.m_hWnd);
	  HDC memdc=::CreateCompatibleDC(hdc);
	  HBITMAP hBmp2=(HBITMAP)SelectObject(memdc,eventsavedlgdc);
  
 
	  SetStretchBltMode(hdc,COLORONCOLOR);  //For better quality
      StretchBlt(hdc,0,0,rectW,rectH,memdc,0,0,752,480,SRCCOPY); 
 
      DeleteDC(hdc);
      DeleteDC(memdc);
 
	  if(eventsavedlgdc)
	  {
			m_Picture.SetBitmap(hBmp2);
			DeleteDC(hMemDC);
			DeleteObject(eventsavedlgdc);
	  }
 
	  capture_ok=true;
	  return FALSE;
}

Open in new window


Avatar of pgnatyukpgnatyuk🇮🇱

In comment ID:25323128 I gave you a link"
"Storing an Image" http://msdn.microsoft.com/en-us/library/dd145119(VS.85).aspx
Right? :)
I attached the code this time. Here you see:
    if (!GetDIBits(hDC, hBMP, 0, (WORD) pbih->biHeight, lpBits, pbi,
        DIB_RGB_COLORS))
 In this way you can get the bit array. Now you need to save it in the memory. The function does it in the file - it calls CreateFile and WriteFile. Insted of that you can use just malloc and memcpy.

Copy Code 
void CreateBMPFile(HWND hwnd, LPTSTR pszFile, PBITMAPINFO pbi, 
                  HBITMAP hBMP, HDC hDC) 
 { 
     HANDLE hf;                 // file handle  
    BITMAPFILEHEADER hdr;       // bitmap file-header  
    PBITMAPINFOHEADER pbih;     // bitmap info-header  
    LPBYTE lpBits;              // memory pointer  
    DWORD dwTotal;              // total count of bytes  
    DWORD cb;                   // incremental count of bytes  
    BYTE *hp;                   // byte pointer  
    DWORD dwTmp; 
 
    pbih = (PBITMAPINFOHEADER) pbi; 
    lpBits = (LPBYTE) GlobalAlloc(GMEM_FIXED, pbih->biSizeImage);
 
    if (!lpBits) 
         errhandler("GlobalAlloc", hwnd); 
 
    // Retrieve the color table (RGBQUAD array) and the bits  
    // (array of palette indices) from the DIB.  
    if (!GetDIBits(hDC, hBMP, 0, (WORD) pbih->biHeight, lpBits, pbi, 
        DIB_RGB_COLORS)) 
    {
        errhandler("GetDIBits", hwnd); 
    }
 
    // Create the .BMP file.  
    hf = CreateFile(pszFile, 
                   GENERIC_READ | GENERIC_WRITE, 
                   (DWORD) 0, 
                    NULL, 
                   CREATE_ALWAYS, 
                   FILE_ATTRIBUTE_NORMAL, 
                   (HANDLE) NULL); 
    if (hf == INVALID_HANDLE_VALUE) 
        errhandler("CreateFile", hwnd); 
    hdr.bfType = 0x4d42;        // 0x42 = "B" 0x4d = "M"  
    // Compute the size of the entire file.  
    hdr.bfSize = (DWORD) (sizeof(BITMAPFILEHEADER) + 
                 pbih->biSize + pbih->biClrUsed 
                 * sizeof(RGBQUAD) + pbih->biSizeImage); 
    hdr.bfReserved1 = 0; 
    hdr.bfReserved2 = 0; 
 
    // Compute the offset to the array of color indices.  
    hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) + 
                    pbih->biSize + pbih->biClrUsed 
                    * sizeof (RGBQUAD); 
 
    // Copy the BITMAPFILEHEADER into the .BMP file.  
    if (!WriteFile(hf, (LPVOID) &hdr, sizeof(BITMAPFILEHEADER), 
        (LPDWORD) &dwTmp,  NULL)) 
    {
       errhandler("WriteFile", hwnd); 
    }
 
    // Copy the BITMAPINFOHEADER and RGBQUAD array into the file.  
    if (!WriteFile(hf, (LPVOID) pbih, sizeof(BITMAPINFOHEADER) 
                  + pbih->biClrUsed * sizeof (RGBQUAD), 
                  (LPDWORD) &dwTmp, ( NULL)))
        errhandler("WriteFile", hwnd); 
 
    // Copy the array of color indices into the .BMP file.  
    dwTotal = cb = pbih->biSizeImage; 
    hp = lpBits; 
    if (!WriteFile(hf, (LPSTR) hp, (int) cb, (LPDWORD) &dwTmp,NULL)) 
           errhandler("WriteFile", hwnd); 
 
    // Close the .BMP file.  
     if (!CloseHandle(hf)) 
           errhandler("CloseHandle", hwnd); 
 
    // Free memory.  
    GlobalFree((HGLOBAL)lpBits);
}

Open in new window


Avatar of pgnatyukpgnatyuk🇮🇱

BTW, you load the image from the file:
eventsavedlgdc = (HBITMAP)::LoadImage(NULL,"readframes01.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
if you need to save it, can you show me a fucntion/method where you are going to save it?
I see only it:
if(!cp.image.Save("readframes01.bmp", GX_BMP))
{
gx_geterror(&ecode, ebuf, sizeof(ebuf));
return TRUE;
}
 So I can propose you to add a function Save. So you code will work.
 I'm afraid, I will confuse you, because I proposed 2 ways for you:
1. ID:25323427 - implement the function youself based on the fucntion showed in this comment.
2. Use the function attached to this comment.
If I still don't understand your requirements, I'm stopping to comment here. Sorry.

 

#include <atlimage.h>
#include <Gdiplusimaging.h>
//here is the implamentation of the class
void Save(CBitmap& bmp)
{
  CImage image;
  image.Attach(bmp);
  image.Save("readframes01.bmp", Gdiplus::ImageFormatBMP); 
}

Open in new window


Free T-shirt

Get a FREE t-shirt when you ask your first question.

We believe in human intelligence. Our moderation policy strictly prohibits the use of LLM content in our Q&A threads.


Hi,

A question, but not really on the scope of the goal of my post, concerning data in memory, can I do this to write a file into a buffer ?

Thank you

//GLOBAL VARIABLES
FILE * fpWrite; 
void * buffer;    
long lSizeOfFile = -1;	
 
 
//CODE	
fpWrite=fopen("test.bmp", "rb");
// get the file size
fseek (fpWrite , 0 , SEEK_END);
lSizeOfFile = ftell (fpWrite);
rewind (fpWrite);
// allocate memory to contain the whole file.
buffer = (char*) malloc (lSizeOfFile);
// read the file into the buffer. 
fread (buffer,1,lSizeOfFile,fpWrite);    
 
 
//TEST THE CONTAIN OF BUFFER
//display contain of the buffer 
CString FullName =buffer;
m_label_buffer.SetWindowText(FullName);

Open in new window


Hi Develprog,
                        To saving HBITMAP to memory you can use the following function


HANDLE DDBToDIB( HBITMAP hBitmap, DWORD dwCompression,BITMAPINFO* pInfo, unsigned char **ppBits )
{
      BITMAP                  bm;
      BITMAPINFOHEADER      bi;
      LPBITMAPINFOHEADER       lpbi;
      DWORD                  dwLen;
      HANDLE                  hDIB;
      HANDLE                  handle;
      HDC                   hDC;
      HPALETTE            hPal;
    CPalette* pPal = new CPalette();

      ASSERT( hBitmap );

      // The function has no arg for bitfields
      if( dwCompression == BI_BITFIELDS )
            return NULL;

      // If a palette has not been supplied use defaul palette
      hPal = (HPALETTE) pPal->GetSafeHandle();
      if (hPal==NULL)
            hPal = (HPALETTE) GetStockObject(DEFAULT_PALETTE);

      // Get bitmap information
      ::GetObject(hBitmap,sizeof(bm),(LPSTR)&bm);

      // Initialize the bitmapinfoheader
      bi.biSize            = sizeof(BITMAPINFOHEADER);
      bi.biWidth            = bm.bmWidth;
      bi.biHeight             = bm.bmHeight;
      bi.biPlanes             = 1;
      bi.biBitCount            = bm.bmPlanes * bm.bmBitsPixel;
      bi.biCompression      = dwCompression;
      bi.biSizeImage            = 0;
      bi.biXPelsPerMeter      = 0;
      bi.biYPelsPerMeter      = 0;
      bi.biClrUsed            = 0;
      bi.biClrImportant      = 0;

      // Compute the size of the  infoheader and the color table
      int nColors = (1 << bi.biBitCount);
      if( nColors > 256 )
            nColors = 0;
      dwLen  = bi.biSize + nColors * sizeof(RGBQUAD);

      // We need a device context to get the DIB from
      hDC = ::GetDC(NULL);
      hPal = SelectPalette(hDC,hPal,FALSE);
      RealizePalette(hDC);

      // Allocate enough memory to hold bitmapinfoheader and color table
      hDIB = GlobalAlloc(GMEM_FIXED,dwLen);

      if (!hDIB){
            SelectPalette(hDC,hPal,FALSE);
            ::ReleaseDC(NULL,hDC);
            return NULL;
      }

      lpbi = (LPBITMAPINFOHEADER)hDIB;

      *lpbi = bi;

      // Call GetDIBits with a NULL lpBits param, so the device driver
      // will calculate the biSizeImage field
      GetDIBits(hDC, hBitmap, 0L, (DWORD)bi.biHeight,
                  (LPBYTE)NULL, (LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS);

      bi = *lpbi;

      // If the driver did not fill in the biSizeImage field, then compute it
      // Each scan line of the image is aligned on a DWORD (32bit) boundary
      if (bi.biSizeImage == 0){
            bi.biSizeImage = ((((bi.biWidth * bi.biBitCount) + 31) & ~31) / 8)
                                    * bi.biHeight;

            // If a compression scheme is used the result may infact be larger
            // Increase the size to account for this.
            if (dwCompression != BI_RGB)
                  bi.biSizeImage = (bi.biSizeImage * 3) / 2;
      }

      // Realloc the buffer so that it can hold all the bits
      dwLen += bi.biSizeImage;
      if (handle = GlobalReAlloc(hDIB, dwLen, GMEM_MOVEABLE))
            hDIB = handle;
      else{
            GlobalFree(hDIB);

            // Reselect the original palette
            SelectPalette(hDC,hPal,FALSE);
            ::ReleaseDC(NULL,hDC);
            return NULL;
      }

      // Get the bitmap bits
      lpbi = (LPBITMAPINFOHEADER)hDIB;

      // FINALLY get the DIB
      BOOL bGotBits = GetDIBits( hDC, hBitmap,
                        0L,                        // Start scan line
                        (DWORD)bi.biHeight,            // # of scan lines
                        (LPBYTE)lpbi                   // address for bitmap bits
                        + (bi.biSize + nColors * sizeof(RGBQUAD)),
                        (LPBITMAPINFO)lpbi,            // address of bitmapinfo
                        (DWORD)DIB_RGB_COLORS);            // Use RGB for color table

      if( !bGotBits )
      {
            GlobalFree(hDIB);

            SelectPalette(hDC,hPal,FALSE);
            ::ReleaseDC(NULL,hDC);
            return NULL;
      }
    *ppBits = (LPBYTE)lpbi  + (bi.biSize + nColors * sizeof(RGBQUAD)),
      memcpy(&pInfo->bmiHeader,lpbi,sizeof(BITMAPINFOHEADER));                  
      SelectPalette(hDC,hPal,FALSE);
      ::ReleaseDC(NULL,hDC);
      delete pPal;
      return hDIB;
}




You can save memory image to Picture control using the code shown down
This DIB based method here image is saving in memory as unsigned char array
DIB is RGB color model. You can directly edit this unsigned char array for editing color


void CPictureCtrlDlg::OnBnClickedButton1()
{
      HBITMAP hbitmap=(HBITMAP)::LoadImage(NULL,"c:/rot.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
      if(hbitmap==NULL)
      {
            AfxMessageBox("image not found");
            return ;
      }
      BITMAPINFO OriginalInfo;
      unsigned char *OriginalBits;
      DDBToDIB(hbitmap, BI_RGB,&OriginalInfo,&OriginalBits );
      HDC hdc = ::GetDC(m_Picture.m_hWnd);
      ::StretchDIBits(hdc,0,0,OriginalInfo.bmiHeader.biWidth,OriginalInfo.bmiHeader.biHeight,0,0,OriginalInfo.bmiHeader.biWidth,OriginalInfo.bmiHeader.biHeight,OriginalBits,&OriginalInfo,DIB_RGB_COLORS,SRCCOPY);
      
}

Regards,
Vimal

Avatar of pgnatyukpgnatyuk🇮🇱

fpWrite=fopen("test.bmp", "rb");
You open file "test.bmp" and then read the whole file int the memory.

If you think it is possible with the HBITMAP, you are wrong.
It is not a buffer in the memory. It is a GDI object.
You need to allocate memory separately for BITMAPINFO structure and for the bit array seperately.
BITMAPINFO is just a structure.
The bit array, you can create with CreateDibSection like I showed in ID:25321076. Then you can fill this bit array with the data.
There are 2 functions that give the direct access to his bit-array if you have HBITMAP. These are SetDIBits and GetDIBits.
if in the function from ID:25323427 you will replace the WinAPI fucntions CreateFile and WriteFile with the fopen and fwrite - you will have what you want.


 

Reward 1Reward 2Reward 3Reward 4Reward 5Reward 6

EARN REWARDS FOR ASKING, ANSWERING, AND MORE.

Earn free swag for participating on the platform.


Hi,

Thank you all.
Pqnatyuk about the save function of Camdev, I have only this info :

///******************************************************************************/
/** Saves an image to a mass storage device in the specific file format
 * (ASCII version).
 * @param handle Handle of the module.
 * @param pimage Pointer to the image.
 * @param filename Name of the image file.
 * @param fileformat Format of the image file (see \ref GX_IMGFILEFORMATS).
 * @return On error false is returned and the error code/string in the GX system
 *         is set appropriately ( see gx_geterror() ). */
inline gxi32 gx_saveimagea(gxHANDLE handle, gxIMAGE* pimage,
                                    const char* filename, gxi32 fileformat) {

      struct GX_PARM_SAVEIMAGEA si;
      assert(pimage);
      assert(filename);
      si.pimage = pimage;
      si.filename = filename;
      si.fileformat = fileformat;
      return gx_call(handle, GX_CALL_SAVEIMAGEA, (void *)&si);
}
//*****************************************************************************************/

We can see that there is wrapping.  Yes your suggestion to change file into memory is interresting so why I follow this way.

Vimamalex thank you too, I try your code and that works well with file.

so I have already function that writes DIB on a file and I try to change it to write on memory instead
of to a file (see code)

My call is  in the function WriteWindowToDIB() :

//WriteDIB( szFile, hDIB );
WriteDIBnew( szFile, hDIB );

But I do wrong with WriteDIBnew function how do that,
maybe change LPTSTR szFile ?

Thank you
BOOL WriteWindowToDIB( LPTSTR szFile, CWnd *pWnd )
{
	CBitmap 	bitmap;
	CWindowDC	dc(pWnd);
	CDC 		memDC;
	CRect		rect;
 
	memDC.CreateCompatibleDC(&dc);
 
	pWnd->GetWindowRect(rect);
 
	bitmap.CreateCompatibleBitmap(&dc, rect.Width(),rect.Height() );
 
	CBitmap* pOldBitmap = memDC.SelectObject(&bitmap);
	memDC.BitBlt(0, 0, rect.Width(),rect.Height(), &dc, 0, 0, SRCCOPY);
 
	// Create logical palette if device support a palette
	CPalette pal;
	if( dc.GetDeviceCaps(RASTERCAPS) & RC_PALETTE )
	{
		UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * 256);
		LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];
		pLP->palVersion = 0x300;
 
		pLP->palNumEntries =
			GetSystemPaletteEntries( dc, 0, 255, pLP->palPalEntry );
 
		// Create the palette
		pal.CreatePalette( pLP );
 
		delete[] pLP;
	}
 
	memDC.SelectObject(pOldBitmap);
 
	// Convert the bitmap to a DIB
	HANDLE hDIB = DDBToDIB( bitmap, BI_RGB, &pal );
 
	if( hDIB == NULL )
		return FALSE;
 
	//char *buff;
	// Write it to file
	//WriteDIB( szFile, hDIB );
	WriteDIBnew( szFile, hDIB );
	// Free the memory allocated by DDBToDIB for the DIB
	GlobalFree( hDIB );
	return TRUE;
}
 
 
 
 
// WriteDIB		- Writes a DIB to file
// Returns		- TRUE on success
// szFile		- Name of file to write to
// hDIB			- Handle of the DIB
BOOL WriteDIB( LPTSTR szFile, HANDLE hDIB)
{
	BITMAPFILEHEADER	hdr;
	LPBITMAPINFOHEADER	lpbi;
 
	if (!hDIB)
		return FALSE;
 
	CFile file;
	if( !file.Open( szFile, CFile::modeWrite|CFile::modeCreate) )
		return FALSE;
 
	lpbi = (LPBITMAPINFOHEADER)hDIB;
 
	int nColors = 1 << lpbi->biBitCount;
 
	// Fill in the fields of the file header 
	hdr.bfType		= ((WORD) ('M' << 8) | 'B');	// is always "BM"
	hdr.bfSize		= GlobalSize (hDIB) + sizeof( hdr );
	hdr.bfReserved1 	= 0;
	hdr.bfReserved2 	= 0;
	hdr.bfOffBits		= (DWORD) (sizeof( hdr ) + lpbi->biSize +
						nColors * sizeof(RGBQUAD));
 
	// Write the file header 
	file.Write( &hdr, sizeof(hdr) );
 
	// Write the DIB header and the bits 
	file.Write( lpbi, GlobalSize(hDIB) );
	
	file.Close(); //
	return TRUE;
}
 
 
//test new to change destination (not to a file but into memory)
BOOL WriteDIBnew( void* buf, HANDLE hDIB)
{
	BITMAPFILEHEADER	hdr;
	LPBITMAPINFOHEADER	lpbi;
 
	if (!hDIB)
		return FALSE;
 
	buf= malloc(65000);
 
	//CFile file;
	//if( !file.Open( szFile, CFile::modeWrite|CFile::modeCreate) )
	//	return FALSE;
 
	lpbi = (LPBITMAPINFOHEADER)hDIB;
 
	int nColors = 1 << lpbi->biBitCount;
 
	// Fill in the fields of the file header 
	hdr.bfType		= ((WORD) ('M' << 8) | 'B');	// is always "BM"
	hdr.bfSize		= GlobalSize (hDIB) + sizeof( hdr );
	hdr.bfReserved1 	= 0;
	hdr.bfReserved2 	= 0;
	hdr.bfOffBits		= (DWORD) (sizeof( hdr ) + lpbi->biSize +
						nColors * sizeof(RGBQUAD));
 
	// Write the file header 
	//file.Write( &hdr, sizeof(hdr) );
	memcpy(buf,&hdr, sizeof(hdr));
 
	// Write the DIB header and the bits 
	//file.Write( lpbi, GlobalSize(hDIB) );
	memcpy(buf,lpbi, GlobalSize(hDIB));
 
	//used global bmp data variable to get bmp data everywhere
	memcpy(gl_buf,buf, sizeof(buf));
 
	//free(buf);
	//file.Close(); //
	return TRUE;
}

Open in new window


Hi,

Sorry I call this function like that :

//Save bitmap to a file
WriteWindowToDIB("test.bmp", this->GetActiveWindow() );  //ok

Thank you.

HI Develprog,
                      Is your problem solved.
Regards,
Vimal Alex

Free T-shirt

Get a FREE t-shirt when you ask your first question.

We believe in human intelligence. Our moderation policy strictly prohibits the use of LLM content in our Q&A threads.


Hi vimalalex,

Not yet I have some trouble to change
WriteDIB() to WriteDIBnew() to obtain a data savced on memory than on file.
So I debug and compiler show errors here:

      // Write the file header
      //file.Write( &hdr, sizeof(hdr) );
      memcpy(buf,&hdr, sizeof(hdr));
 
      // Write the DIB header and the bits
      //file.Write( lpbi, GlobalSize(hDIB) );
      memcpy(buf,lpbi, GlobalSize(hDIB));  //Error
 
 
I do rewrite at buf. So how can I add correctly the hdr and lpbi variables to my buffer ?

Thank you

HI Develprog,
               Please explain me some more detail what you mean by memory, you what to write to RAM or any
other memory from where to where.
Are you want to copy DIB HANDLE  to char pointer
Or you want to copy HBITMAP to char pointer or other.

Regards,
Vimal Alex

Hi Vimamalex,

I mean by memory in fact a void* or a char* where I will save my bmp data.

And now how to know WHAT ( DIB HANDLE or HBITMAP) to save ?

To respond to this last question firts thing to know is that after each save (write) to memory we must do a read into memory of that saved data for display it.  
When saving file to disk we used this function:

eventsavedlgdc = (HBITMAP)::LoadImage(NULL,"readframes01.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);  //BON

Now we try to write to memory and for the moment we have a working functions that change a DDB data to a DIB. And the WriteDIB( szFile, hDIB ) funtion saves well a DIB format but into a file.
(For the moment I try to change WriteDIB to save into a memory)

So because of we have already funtions that can save DIBformat, Iet suppose we use a DIB format than a HBITMAP format. So for the next step, the problem is how to load this saved DIB format from the memory with the LoadImage of HBITMAP by using different parameter than LR_LOADFROMFILE?  If yes, maybe like this :

eventsavedlgdc = (HBITMAP)::LoadImage(NULL,gl_buf, IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION);

is it right ?

Thank you



 

  to display bmap data

Reward 1Reward 2Reward 3Reward 4Reward 5Reward 6

EARN REWARDS FOR ASKING, ANSWERING, AND MORE.

Earn free swag for participating on the platform.


HI Develprog,
       Try with the below code to copy from DIB handle to a buffer

        unsigned char *buff;
       unsigned char* pDIB = (unsigned char *)GlobalLock(hDIB);
      BITMAPINFO pInfo;
      PBITMAPINFOHEADER pbih = (PBITMAPINFOHEADER)pDIB;
 
      memset(&pInfo,0,sizeof(BITMAPINFO));
      memcpy(&(pInfo.bmiHeader),pbih,sizeof(BITMAPINFOHEADER));

      DWORD  bfOffBits = pbih->biSize + pbih->biClrUsed * sizeof (RGBQUAD);
      buff=pDIB+bfOffBits;

      GlobalUnlock(hDIB);

                     In the buff variable you can get the DIB RGB data that you can use for displaying or
saving in the file as .bmp file

Hi Vimalalex,

I try like this I don't know if it is good way (see code)
and my call to this function is :

BOOL WriteWindowToDIB( LPTSTR szFile, CWnd *pWnd )
{

...
      gl_buf = (const char*)malloc (2000000);
      // Write it to file
                   //      WriteDIB( szFile, hDIB );
                     //write to memory
      WriteDIBnew( gl_buf, hDIB );
...
}


And my test to load from memory is :


void CTest_Load_BmpDlg::OnButtonLoadfrommem()
{
      
//here loading from gl_buf (from memory)
      HBITMAP hbitmap=(HBITMAP)::LoadImage(NULL,gl_buf,IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION);
      if(hbitmap==NULL)
      {
            AfxMessageBox("image not found");
            return ;
      }

      BITMAPINFO OriginalInfo;
      unsigned char *OriginalBits;
      DDBToDIBnew(hbitmap, BI_RGB,&OriginalInfo,&OriginalBits );
      HDC hdc = ::GetDC(m_Picturebox.m_hWnd);
      ::StretchDIBits(hdc,0,0,OriginalInfo.bmiHeader.biWidth,OriginalInfo.bmiHeader.biHeight,0,0,OriginalInfo.bmiHeader.biWidth,OriginalInfo.bmiHeader.biHeight,OriginalBits,&OriginalInfo,DIB_RGB_COLORS,SRCCOPY);
     
  CBitmap test;
  test.Attach(hdc);
   m_Picturebox.SetBitmap(test);

}


The result of OnButtonLoadfrommem() gives "image not found", maybe the problem is in the loadImage of HBITMAP ?

How can I fix it ?
Thank you




//test new add
BOOL WriteDIBnew( const char* buf, HANDLE hDIB)
{
	BITMAPFILEHEADER	hdr;
	LPBITMAPINFOHEADER	lpbi;
 
	if (!hDIB)
		return FALSE;
 
	buf= (const char*)malloc(65000);
	//CFile file;
	//if( !file.Open( szFile, CFile::modeWrite|CFile::modeCreate) )
	//return FALSE;
 
	lpbi = (LPBITMAPINFOHEADER)hDIB;
 
	int nColors = 1 << lpbi->biBitCount;
 
	// Fill in the fields of the file header 
	hdr.bfType		= ((WORD) ('M' << 8) | 'B');	// is always "BM"
	hdr.bfSize		= GlobalSize (hDIB) + sizeof( hdr );
	hdr.bfReserved1 	= 0;
	hdr.bfReserved2 	= 0;
	hdr.bfOffBits	= (DWORD) (sizeof( hdr ) + lpbi->biSize +
				nColors * sizeof(RGBQUAD));
 
	// Write the file header 
	//file.Write( &hdr, sizeof(hdr) );
	//memcpy((void*)buf,&hdr, sizeof(hdr));
 
	// Write the DIB header and the bits 
	//file.Write( lpbi, GlobalSize(hDIB) );
 
//memcpy(buf,lpbi, GlobalSize(hDIB));
 
//free(buf);
//file.Close(); //
//     unsigned char *buff;
       const char *buff;
       unsigned char* pDIB = (unsigned char *)GlobalLock(hDIB); 
      BITMAPINFO pInfo;
      PBITMAPINFOHEADER pbih = (PBITMAPINFOHEADER)pDIB;
 
      memset(&pInfo,0,sizeof(BITMAPINFO));
      memcpy(&(pInfo.bmiHeader),pbih,sizeof(BITMAPINFOHEADER));
 
      DWORD  bfOffBits = pbih->biSize + pbih->biClrUsed * sizeof (RGBQUAD); 
      //buff=pDIB+bfOffBits;
     gl_buf=(const char*)pDIB+bfOffBits;
 
      GlobalUnlock(hDIB); 
 
	return TRUE;
}

Open in new window


HI Develprog,
               Let me know one thing how you are loading to gl_buf
The result of OnButtonLoadfrommem() gives "image not found", I think image data  the gl_buf is not a valid DIB format. So please let me know how you are loading to gl_buf.

 Are you starting loading the image from a .bmp or you are creating bitmap dynamically using code . And please give me you exact requirement because you are doing too much complexly. So i think if u are giving your actual requirement what you are trying to do. I can help you you in a better way. What ever code i have given to you i have checked with in my machine and it is working fine here.

Regards,
Vimal Alex

Free T-shirt

Get a FREE t-shirt when you ask your first question.

We believe in human intelligence. Our moderation policy strictly prohibits the use of LLM content in our Q&A threads.


Hi Vimalalex,

You are right, In fact I made a test application.
This aplication is a Dialog based application in which I have 4 controls (a Picure BOX and
3 Buttons),

-Picture box : IDC_PICTUREBOX  with a variable CStatic m_picturebox
-Button IDC_BUTTON_LOADFRMFILE
-Button IDC_BUTTON_SAVETOMEM
-Button IDC_BUTTON_LOADFROMMEM

 this application makes 3 basic things:
- load an image (Image300x200.bmp) from a file, displays it to the picture control
- after that, it saves to another a bmp file (test.bmp) the active window image.
- and finally this application reloads the saved test.bmp to display it in the picture box

This application works well with file manipulation.


The modified new application that we try to do here make 3 things detailled:

1. I load a bmp file (Image300x200.bmp,  256 colors) in the Piture control with a classic LoadImage funtion (with parameter LR_LOADFROMFILE).  (See code 1, OnButtonLoadfrmfile() )

2. We Convert the bitmap bitmap (active window) to a DIB and save it to a bmp file ( test.bmp) and too into a buffer.    (See code 2, OnButtonSavetomem()  + WriteWindowToDIB() + DDBToDIB() + WriteDIBnew( ) )  
            
3. We load the saved bmp file ( test.bmp)  to display it in the picture box.  
  (See code 3, OnButtonLoadfrommem()   + DDBToDIBnew())  

The program compil well but we have  Exception error USER32! 77d3e76() when entry here :

    HBITMAP hbitmap=(HBITMAP)::LoadImage(NULL,gl_buf,IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION);
      if(hbitmap==NULL)
      {
            AfxMessageBox("image not found");
            return ;
      }



I do like you said but there is somthing wrong somwhere I don't know.
You can see in code2 and code3 that the functions DDBToDIB are little different.

Thank you.



 

//Global variables
HBITMAP HImagebmp; 
HBITMAP hBmp2;
RECT rectScaled;
int rectW;
int rectH;
 
 
FILE * fpWrite; 
char * buffer;    
long lSizeOfFile = -1;	
 
const char * gl_buf;
	  
	  
 
 //CODE1
void CTest_Load_BmpDlg::OnButtonLoadfrmfile() 
{
	  HImagebmp = (HBITMAP)::LoadImage(NULL,"Image300x200.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);  //BON  
 
	  HDC hdc=::GetDC(m_Picturebox.m_hWnd);
	  HDC memdc=::CreateCompatibleDC(hdc);
	  hBmp2=(HBITMAP)SelectObject(memdc,HImagebmp);
  
	 // SetStretchBltMode(hdc,COLORONCOLOR);  //For better quality
      StretchBlt(hdc,0,0,rectW,rectH,memdc,0,0,300,200,SRCCOPY); 
 
      DeleteDC(hdc);
      DeleteDC(memdc);
 
	  if(HImagebmp)
	  {
			m_Picturebox.SetBitmap(hBmp2);
			DeleteObject(HImagebmp);
	  }
}
 
 
 
//CODE2
void CTest_Load_BmpDlg::OnButtonSavetomem() 
{
 
	WriteWindowToDIB("test.bmp", /*pWnd*/ this->GetActiveWindow() ); //this->GetActiveWindow()           ==> ok
														   //this->GetDlgItem(IDC_PICTUREBOX); ==> blank ?
 
}
 
 
BOOL WriteWindowToDIB( LPTSTR szFile, CWnd *pWnd )
{
	CBitmap 	bitmap;
	CWindowDC	dc(pWnd);
	CDC 		memDC;
	CRect		rect;
 
	memDC.CreateCompatibleDC(&dc);
 
	pWnd->GetWindowRect(rect);
 
	bitmap.CreateCompatibleBitmap(&dc, rect.Width(),rect.Height() );
 
	CBitmap* pOldBitmap = memDC.SelectObject(&bitmap);
	memDC.BitBlt(0, 0, rect.Width(),rect.Height(), &dc, 0, 0, SRCCOPY);
 
	// Create logical palette if device support a palette
	CPalette pal;
	if( dc.GetDeviceCaps(RASTERCAPS) & RC_PALETTE )
	{
		UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * 256);
		LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];
		pLP->palVersion = 0x300;
 
		pLP->palNumEntries =
			GetSystemPaletteEntries( dc, 0, 255, pLP->palPalEntry );
 
		// Create the palette
		pal.CreatePalette( pLP );
 
		delete[] pLP;
	}
	memDC.SelectObject(pOldBitmap);
	// Convert the bitmap to a DIB
	HANDLE hDIB = DDBToDIB( bitmap, BI_RGB, &pal );
 
	if( hDIB == NULL )
		return FALSE;
 
	gl_buf = (const char*)malloc (1900000);
	//char *buff;
	// Write it to file
	//WriteDIB( szFile, hDIB );
	WriteDIBnew( gl_buf, hDIB );
 
	// Free the memory allocated by DDBToDIB for the DIB
	GlobalFree( hDIB );
	return TRUE;
}
 
// DDBToDIB		- Creates a DIB from a DDB
// bitmap		- Device dependent bitmap
// dwCompression	- Type of compression - see BITMAPINFOHEADER
// pPal			- Logical palette
HANDLE DDBToDIB( CBitmap& bitmap, DWORD dwCompression, CPalette* pPal )
{
	BITMAP			bm;
	BITMAPINFOHEADER	bi;
	LPBITMAPINFOHEADER 	lpbi;
	DWORD			dwLen;
	HANDLE			hDIB;
	HANDLE			handle;
	HDC 			hDC;
	HPALETTE		hPal;
 
 
	ASSERT( bitmap.GetSafeHandle() );
 
	// The function has no arg for bitfields
	if( dwCompression == BI_BITFIELDS )
		return NULL;
 
	// If a palette has not been supplied use defaul palette
	hPal = (HPALETTE) pPal->GetSafeHandle();
	if (hPal==NULL)
		hPal = (HPALETTE) GetStockObject(DEFAULT_PALETTE);
 
	// Get bitmap information
	bitmap.GetObject(sizeof(bm),(LPSTR)&bm);
 
	// Initialize the bitmapinfoheader
	bi.biSize		= sizeof(BITMAPINFOHEADER);
	bi.biWidth		= bm.bmWidth;
	bi.biHeight 		= bm.bmHeight;
	bi.biPlanes 		= 1;
	bi.biBitCount		= bm.bmPlanes * bm.bmBitsPixel;
	bi.biCompression	= dwCompression;
	bi.biSizeImage		= 0;
	bi.biXPelsPerMeter	= 0;
	bi.biYPelsPerMeter	= 0;
	bi.biClrUsed		= 0;
	bi.biClrImportant	= 0;
 
	// Compute the size of the  infoheader and the color table
	int nColors = (1 << bi.biBitCount);
	if( nColors > 256 )
		nColors = 0;
	dwLen  = bi.biSize + nColors * sizeof(RGBQUAD);
 
	// We need a device context to get the DIB from
	hDC = GetDC(NULL);
	hPal = SelectPalette(hDC,hPal,FALSE);
	RealizePalette(hDC);
 
	// Allocate enough memory to hold bitmapinfoheader and color table
	hDIB = GlobalAlloc(GMEM_FIXED,dwLen);
 
	if (!hDIB){
		SelectPalette(hDC,hPal,FALSE);
		ReleaseDC(NULL,hDC);
		return NULL;
	}
 
	lpbi = (LPBITMAPINFOHEADER)hDIB;
 
	*lpbi = bi;
 
	// Call GetDIBits with a NULL lpBits param, so the device driver 
	// will calculate the biSizeImage field 
	GetDIBits(hDC, (HBITMAP)bitmap.GetSafeHandle(), 0L, (DWORD)bi.biHeight,
			(LPBYTE)NULL, (LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS);
 
	bi = *lpbi;
 
	// If the driver did not fill in the biSizeImage field, then compute it
	// Each scan line of the image is aligned on a DWORD (32bit) boundary
	if (bi.biSizeImage == 0){
		bi.biSizeImage = ((((bi.biWidth * bi.biBitCount) + 31) & ~31) / 8)
						* bi.biHeight;
 
		// If a compression scheme is used the result may infact be larger
		// Increase the size to account for this.
		if (dwCompression != BI_RGB)
			bi.biSizeImage = (bi.biSizeImage * 3) / 2;
	}
 
	// Realloc the buffer so that it can hold all the bits
	dwLen += bi.biSizeImage;
	if (handle = GlobalReAlloc(hDIB, dwLen, GMEM_MOVEABLE))
		hDIB = handle;
	else{
		GlobalFree(hDIB);
 
		// Reselect the original palette
		SelectPalette(hDC,hPal,FALSE);
		ReleaseDC(NULL,hDC);
		return NULL;
	}
 
	// Get the bitmap bits
	lpbi = (LPBITMAPINFOHEADER)hDIB;
 
	// FINALLY get the DIB
	BOOL bGotBits = GetDIBits( hDC, (HBITMAP)bitmap.GetSafeHandle(),
				0L,				// Start scan line
				(DWORD)bi.biHeight,		// # of scan lines
				(LPBYTE)lpbi 			// address for bitmap bits
				+ (bi.biSize + nColors * sizeof(RGBQUAD)),
				(LPBITMAPINFO)lpbi,		// address of bitmapinfo
				(DWORD)DIB_RGB_COLORS);		// Use RGB for color table
 
	if( !bGotBits )
	{
		GlobalFree(hDIB);
 
		SelectPalette(hDC,hPal,FALSE);
		ReleaseDC(NULL,hDC);
		return NULL;
	}
 
	SelectPalette(hDC,hPal,FALSE);
	ReleaseDC(NULL,hDC);
	return hDIB;
}
 
//test new add
BOOL WriteDIBnew( const char* buf, HANDLE hDIB)
{
	BITMAPFILEHEADER	hdr;
	LPBITMAPINFOHEADER	lpbi;
 
	if (!hDIB)
		return FALSE;
 
	buf= (const char*)malloc(65000);
 
	//CFile file;
	//if( !file.Open( szFile, CFile::modeWrite|CFile::modeCreate) )
	//	return FALSE;
 
	lpbi = (LPBITMAPINFOHEADER)hDIB;
 
	int nColors = 1 << lpbi->biBitCount;
 
	// Fill in the fields of the file header 
	hdr.bfType		= ((WORD) ('M' << 8) | 'B');	// is always "BM"
	hdr.bfSize		= GlobalSize (hDIB) + sizeof( hdr );
	hdr.bfReserved1 	= 0;
	hdr.bfReserved2 	= 0;
	hdr.bfOffBits		= (DWORD) (sizeof( hdr ) + lpbi->biSize +
						nColors * sizeof(RGBQUAD));
 
	// Write the file header 
	//file.Write( &hdr, sizeof(hdr) );
    //memcpy((void*)buf,&hdr, sizeof(hdr));
 
	// Write the DIB header and the bits 
	//file.Write( lpbi, GlobalSize(hDIB) );
 
    //memcpy(buf,lpbi, GlobalSize(hDIB));
 
	//used global bmp data variable to get bmp data everywhere
    //memcpy(gl_buf,buf, sizeof(buf));
 
	//free(buf);
	//file.Close(); //
    //unsigned char *buff;
       const char *buff;
       unsigned char* pDIB = (unsigned char *)GlobalLock(hDIB); 
      BITMAPINFO pInfo;
      PBITMAPINFOHEADER pbih = (PBITMAPINFOHEADER)pDIB;
 
      memset(&pInfo,0,sizeof(BITMAPINFO));
      memcpy(&(pInfo.bmiHeader),pbih,sizeof(BITMAPINFOHEADER));
 
      DWORD  bfOffBits = pbih->biSize + pbih->biClrUsed * sizeof (RGBQUAD); 
      //buff=pDIB+bfOffBits;
	  gl_buf=(const char*)(pDIB+bfOffBits);
 
      GlobalUnlock(hDIB); 
 
	return TRUE;
}
 
 
 
 
 
 
//CODE3
void CTest_Load_BmpDlg::OnButtonLoadfrommem() 
{
 
		CString FullName =buffer;
		//CString FullName =gl_buf;
		m_label_buffer.SetWindowText(FullName);
 
 
/*
      HBITMAP hbitmap=(HBITMAP)::LoadImage(NULL,"test.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
      if(hbitmap==NULL)
      {
            AfxMessageBox("image not found");
            return ;
      }
*/
 
//gl_buf
 
      HBITMAP hbitmap=(HBITMAP)::LoadImage(NULL,gl_buf,IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION);
      if(hbitmap==NULL)
      {
            AfxMessageBox("image not found");
            return ;
      }
	
	
      BITMAPINFO OriginalInfo;
      unsigned char *OriginalBits;
      DDBToDIBnew(hbitmap, BI_RGB,&OriginalInfo,&OriginalBits );
      HDC hdc = ::GetDC(m_Picturebox.m_hWnd);
      ::StretchDIBits(hdc,0,0,OriginalInfo.bmiHeader.biWidth,OriginalInfo.bmiHeader.biHeight,0,0,OriginalInfo.bmiHeader.biWidth,OriginalInfo.bmiHeader.biHeight,OriginalBits,&OriginalInfo,DIB_RGB_COLORS,SRCCOPY);
      
	  CBitmap test;
	  test.Attach(hdc);
	   m_Picturebox.SetBitmap(test);
 
	  
}
//new test other funtion and signature
HANDLE DDBToDIBnew( HBITMAP hBitmap, DWORD dwCompression,BITMAPINFO* pInfo, unsigned char **ppBits )
{
	  BITMAP                  bm;
	  BITMAPINFOHEADER      bi;
	  LPBITMAPINFOHEADER       lpbi;
	  DWORD                  dwLen;
	  HANDLE                  hDIB;
	  HANDLE                  handle;
	  HDC                   hDC;
	  HPALETTE            hPal;
	CPalette* pPal = new CPalette(); 
 
	  ASSERT( hBitmap );
 
	  // The function has no arg for bitfields
	  if( dwCompression == BI_BITFIELDS )
			return NULL;
 
	  // If a palette has not been supplied use defaul palette
	  hPal = (HPALETTE) pPal->GetSafeHandle();
	  if (hPal==NULL)
			hPal = (HPALETTE) GetStockObject(DEFAULT_PALETTE);
 
	  // Get bitmap information
	  ::GetObject(hBitmap,sizeof(bm),(LPSTR)&bm);
 
	  // Initialize the bitmapinfoheader
	  bi.biSize            = sizeof(BITMAPINFOHEADER);
	  bi.biWidth            = bm.bmWidth;
	  bi.biHeight             = bm.bmHeight;
	  bi.biPlanes             = 1;
	  bi.biBitCount            = bm.bmPlanes * bm.bmBitsPixel;
	  bi.biCompression      = dwCompression;
	  bi.biSizeImage            = 0;
	  bi.biXPelsPerMeter      = 0;
	  bi.biYPelsPerMeter      = 0;
	  bi.biClrUsed            = 0;
	  bi.biClrImportant      = 0;
 
	  // Compute the size of the  infoheader and the color table
	  int nColors = (1 << bi.biBitCount);
	  if( nColors > 256 )
			nColors = 0;
	  dwLen  = bi.biSize + nColors * sizeof(RGBQUAD);
 
	  // We need a device context to get the DIB from
	  hDC = ::GetDC(NULL);
	  hPal = SelectPalette(hDC,hPal,FALSE);
	  RealizePalette(hDC);
 
	  // Allocate enough memory to hold bitmapinfoheader and color table
	  hDIB = GlobalAlloc(GMEM_FIXED,dwLen);
 
	  if (!hDIB){
			SelectPalette(hDC,hPal,FALSE);
			::ReleaseDC(NULL,hDC);
			return NULL;
	  }
 
	  lpbi = (LPBITMAPINFOHEADER)hDIB;
 
	  *lpbi = bi;
 
	  // Call GetDIBits with a NULL lpBits param, so the device driver 
	  // will calculate the biSizeImage field 
	  GetDIBits(hDC, hBitmap, 0L, (DWORD)bi.biHeight,
				  (LPBYTE)NULL, (LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS);
 
	  bi = *lpbi;
 
	  // If the driver did not fill in the biSizeImage field, then compute it
	  // Each scan line of the image is aligned on a DWORD (32bit) boundary
	  if (bi.biSizeImage == 0){
			bi.biSizeImage = ((((bi.biWidth * bi.biBitCount) + 31) & ~31) / 8)
									* bi.biHeight;
 
			// If a compression scheme is used the result may infact be larger
			// Increase the size to account for this.
			if (dwCompression != BI_RGB)
				  bi.biSizeImage = (bi.biSizeImage * 3) / 2;
	  }
 
	  // Realloc the buffer so that it can hold all the bits
	  dwLen += bi.biSizeImage;
	  if (handle = GlobalReAlloc(hDIB, dwLen, GMEM_MOVEABLE))
			hDIB = handle;
	  else{
			GlobalFree(hDIB);
 
			// Reselect the original palette
			SelectPalette(hDC,hPal,FALSE);
			::ReleaseDC(NULL,hDC);
			return NULL;
	  }
 
	  // Get the bitmap bits
	  lpbi = (LPBITMAPINFOHEADER)hDIB;
 
	  // FINALLY get the DIB
	  BOOL bGotBits = GetDIBits( hDC, hBitmap,
						0L,                        // Start scan line
						(DWORD)bi.biHeight,            // # of scan lines
						(LPBYTE)lpbi                   // address for bitmap bits
						+ (bi.biSize + nColors * sizeof(RGBQUAD)),
						(LPBITMAPINFO)lpbi,            // address of bitmapinfo
						(DWORD)DIB_RGB_COLORS);            // Use RGB for color table
 
	  if( !bGotBits )
	  {
			GlobalFree(hDIB);
 
			SelectPalette(hDC,hPal,FALSE);
			::ReleaseDC(NULL,hDC);
			return NULL;
	  }
	*ppBits = (LPBYTE)lpbi  + (bi.biSize + nColors * sizeof(RGBQUAD)),
	  memcpy(&pInfo->bmiHeader,lpbi,sizeof(BITMAPINFOHEADER));                  
	  SelectPalette(hDC,hPal,FALSE);
	  ::ReleaseDC(NULL,hDC);
	  delete pPal;
	  return hDIB;
}

Open in new window



Hi Vimalalex,

the application test that i explain in my precedent post is almost the same of my original application
at the difference of saving into memory. In the original application there is already a function SaveToMem in the class Camdev (see below):

//global variables
void *Gl_buffer = 0;
int Gl_buflen = 0;

//function
cp.image.SaveToMem(&Gl_buffer, &Gl_buflen, GX_BMP); //


Sofor this original application, the only thing to do is to load this bmp data from the memory (Gl_buffer) to the picture control. But the LoadImage of HBITMAP seems not to work. So what can I do ?

Thank you

HI Develprog,
                      Now I am giving the code for saving window to the and displaying it to the window


BOOL WriteDIB(LPTSTR szFile, HANDLE hDIB)
{
      BITMAPFILEHEADER      hdr;
      LPBITMAPINFOHEADER      lpbi;
      if (!hDIB)
            return FALSE;
      CFile file;
      if( !file.Open( szFile, CFile::modeWrite|CFile::modeCreate) )
            return FALSE;
      lpbi = (LPBITMAPINFOHEADER)hDIB;
      int nColors = 1 << lpbi->biBitCount;
      hdr.bfType            = ((WORD) ('M' << 8) | 'B');
      hdr.bfSize            = GlobalSize (hDIB) + sizeof( hdr );
      hdr.bfReserved1       = 0;
      hdr.bfReserved2       = 0;
      hdr.bfOffBits            = (DWORD) (sizeof( hdr ) + lpbi->biSize +
                                    nColors * sizeof(RGBQUAD));
      file.Write( &hdr, sizeof(hdr) );
      file.Write( lpbi, GlobalSize(hDIB) );
      return TRUE;

}

HANDLE DDBToDIB( HBITMAP hBitmap, DWORD dwCompression,BITMAPINFO* pInfo, unsigned char **ppBits )
{
      BITMAP                  bm;
      BITMAPINFOHEADER      bi;
      LPBITMAPINFOHEADER       lpbi;
      DWORD                  dwLen;
      HANDLE                  hDIB;
      HANDLE                  handle;
      HDC                   hDC;
      HPALETTE            hPal;
    CPalette* pPal = new CPalette();

      ASSERT( hBitmap );

      // The function has no arg for bitfields
      if( dwCompression == BI_BITFIELDS )
            return NULL;

      // If a palette has not been supplied use defaul palette
      hPal = (HPALETTE) pPal->GetSafeHandle();
      if (hPal==NULL)
            hPal = (HPALETTE) GetStockObject(DEFAULT_PALETTE);

      // Get bitmap information
      ::GetObject(hBitmap,sizeof(bm),(LPSTR)&bm);

      // Initialize the bitmapinfoheader
      bi.biSize            = sizeof(BITMAPINFOHEADER);
      bi.biWidth            = bm.bmWidth;
      bi.biHeight             = bm.bmHeight;
      bi.biPlanes             = 1;
      bi.biBitCount            = bm.bmPlanes * bm.bmBitsPixel;
      bi.biCompression      = dwCompression;
      bi.biSizeImage            = 0;
      bi.biXPelsPerMeter      = 0;
      bi.biYPelsPerMeter      = 0;
      bi.biClrUsed            = 0;
      bi.biClrImportant      = 0;

      // Compute the size of the  infoheader and the color table
      int nColors = (1 << bi.biBitCount);
      if( nColors > 256 )
            nColors = 0;
      dwLen  = bi.biSize + nColors * sizeof(RGBQUAD);

      // We need a device context to get the DIB from
      hDC = ::GetDC(NULL);
      hPal = SelectPalette(hDC,hPal,FALSE);
      RealizePalette(hDC);

      // Allocate enough memory to hold bitmapinfoheader and color table
      hDIB = GlobalAlloc(GMEM_FIXED,dwLen);

      if (!hDIB){
            SelectPalette(hDC,hPal,FALSE);
            ::ReleaseDC(NULL,hDC);
            return NULL;
      }

      lpbi = (LPBITMAPINFOHEADER)hDIB;

      *lpbi = bi;

      // Call GetDIBits with a NULL lpBits param, so the device driver
      // will calculate the biSizeImage field
      GetDIBits(hDC, hBitmap, 0L, (DWORD)bi.biHeight,
                  (LPBYTE)NULL, (LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS);

      bi = *lpbi;

      // If the driver did not fill in the biSizeImage field, then compute it
      // Each scan line of the image is aligned on a DWORD (32bit) boundary
      if (bi.biSizeImage == 0){
            bi.biSizeImage = ((((bi.biWidth * bi.biBitCount) + 31) & ~31) / 8)
                                    * bi.biHeight;

            // If a compression scheme is used the result may infact be larger
            // Increase the size to account for this.
            if (dwCompression != BI_RGB)
                  bi.biSizeImage = (bi.biSizeImage * 3) / 2;
      }

      // Realloc the buffer so that it can hold all the bits
      dwLen += bi.biSizeImage;
      if (handle = GlobalReAlloc(hDIB, dwLen, GMEM_MOVEABLE))
            hDIB = handle;
      else{
            GlobalFree(hDIB);

            // Reselect the original palette
            SelectPalette(hDC,hPal,FALSE);
            ::ReleaseDC(NULL,hDC);
            return NULL;
      }

      // Get the bitmap bits
      lpbi = (LPBITMAPINFOHEADER)hDIB;

      // FINALLY get the DIB
      BOOL bGotBits = GetDIBits( hDC, hBitmap,
                        0L,                        // Start scan line
                        (DWORD)bi.biHeight,            // # of scan lines
                        (LPBYTE)lpbi                   // address for bitmap bits
                        + (bi.biSize + nColors * sizeof(RGBQUAD)),
                        (LPBITMAPINFO)lpbi,            // address of bitmapinfo
                        (DWORD)DIB_RGB_COLORS);            // Use RGB for color table

      if( !bGotBits )
      {
            GlobalFree(hDIB);

            SelectPalette(hDC,hPal,FALSE);
            ::ReleaseDC(NULL,hDC);
            return NULL;
      }
    *ppBits = (LPBYTE)lpbi  + (bi.biSize + nColors * sizeof(RGBQUAD)),
      memcpy(&pInfo->bmiHeader,lpbi,sizeof(BITMAPINFOHEADER));                  
      SelectPalette(hDC,hPal,FALSE);
      ::ReleaseDC(NULL,hDC);
      delete pPal;
      return hDIB;
}

void CPictureCtrlDlg::OnBnClickedSaveWindow()
{
      RECT lp;
      BITMAPINFO OriginalInfo;
      unsigned char *OriginalBits;
      HDC hdc = ::GetWindowDC(m_hWnd);
      ::GetWindowRect(m_hWnd,&lp);
      HDC hdc1=::GetDC(m_hWnd);
      HDC memDC = CreateCompatibleDC ( hdc );
      HBITMAP hBitMap = ::CreateCompatibleBitmap(hdc,lp.right,lp.bottom);
      ::SelectObject ( memDC, hBitMap );
      ::BitBlt(memDC,0,0,lp.right,lp.bottom,hdc,0,0,SRCCOPY);
      HGLOBAL hDIB =DDBToDIB(hBitMap, BI_RGB,&OriginalInfo,&OriginalBits );
      WriteDIB("c:/temp.bmp",hDIB);
      ::StretchDIBits(hdc1,0,40,OriginalInfo.bmiHeader.biWidth,OriginalInfo.bmiHeader.biHeight,0,0,OriginalInfo.bmiHeader.biWidth,OriginalInfo.bmiHeader.biHeight,OriginalBits,&OriginalInfo,DIB_RGB_COLORS,SRCCOPY);
      ::ReleaseDC(m_hWnd,hdc1);
      ::ReleaseDC(m_hWnd,hdc);
      ::GlobalFree(hDIB);
      ::DeleteObject(hBitMap);
      
}

the above function is displaying the saved window also using the function ::StretchDIBits()

And for loading the image from file and displaying to picture box i have given the code yesterday.

I think this will solve your problem.

Regards,
Vimal Alex

Reward 1Reward 2Reward 3Reward 4Reward 5Reward 6

EARN REWARDS FOR ASKING, ANSWERING, AND MORE.

Earn free swag for participating on the platform.


Hi again  :) ,

Maybe for better seeing the problem, Can I sent my little test application compiled with MS Visual C++6?

Thank you


HI Develprog,

                     Ofcourse, Before that check the above functions in your application by copy paste

Regards,
Vimal Alex

Hi Vimalalex,

Thank you I tested your code by adding a button for OnBnClickedSaveWindow() function
 and that works well, I can see that image is set to my picture box. But I think that there is no data which is saving to memory (void* ) or loading from memory (void*). But unfortunatly because of the original application gaves us a bmp data in a void* so I dont know how can I load this bmp data from memory  into the picture box ?

Thank you  

Free T-shirt

Get a FREE t-shirt when you ask your first question.

We believe in human intelligence. Our moderation policy strictly prohibits the use of LLM content in our Q&A threads.


HI Develprog,

                      Here we are loading image from memory to window by using windows API ::StretchDIBits().
There we are passing OriginalBits variable as a parameter ,OriginalBits is a unsigned char * pointer which is
holding DIB bits of the image .I think you are confused here little bit. All of your requirements are solved here.
And we can load OriginalBits memory data to picture box also.

Regards,
Vimal Alex

Hi Vimalalex,

Thank you,  you are right sorry for the confusion. It is ok for the test application

So finally for my original application between the 2 functions getcaptureImage and DisplayImage . I have still problem to display the catured image to my picture box.
 
How can I  modify my function displayImage() to load the data "Gl_buffer" in the picture box using OriginalBits ? (Please see code below)


Thank you


void *buffer = 0;
int buflen = 0;
 
bool CFXCAMd_ConfiguratorDlg::DisplayImage() 
{
 
	  if (eventsavedlgdc)
	  { 
	    	::DeleteObject(eventsavedlgdc);
	  }
 
	  // eventsavedlgdc = (HBITMAP)::LoadImage(NULL,"readframes01.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);  //BON
	  eventsavedlgdc = ::LoadBitmapFromMemory( Gl_buffer );
 
	  CBitmap bmp;
	  bmp.Attach(eventsavedlgdc);
	  BITMAP bm;
	  bmp.GetBitmap(&bm);  
	  bmp.Detach(); 
 
	  HDC hdc=::GetDC(m_Picture.m_hWnd);
	  HDC memdc=::CreateCompatibleDC(hdc);
	  HBITMAP hBmp2=(HBITMAP)SelectObject(memdc,eventsavedlgdc);
  
	  SetStretchBltMode(hdc,COLORONCOLOR);  //For better qualioty
      StretchBlt(hdc,0,0,rectW,rectH,memdc,0,0,752,480,SRCCOPY); //090907 sur image interne
      DeleteDC(hdc);
      DeleteDC(memdc);
 
	  if(eventsavedlgdc)
	  {
			m_Picture.SetBitmap(hBmp2);
			DeleteDC(hMemDC);
			DeleteObject(eventsavedlgdc);
	  }
 
	  return FALSE;
 
}
    
bool CFXCAMd_ConfiguratorDlg::GetCaptureImage()
{
	
        // Saves the image to the memory
	    try
		{
			//cp.image.Load("readframes01.bmp");
			cp.image.SaveToMem(&Gl_buffer, &Gl_buflen, GX_BMP); //GX_JPEG
 
		}
		catch(...)
		{
			 MessageBox("ERROR IN cp.image.SaveToMem","trycatch message");
 
		}
 
	return FALSE;
 
}

Open in new window


HI Develprog,
                     Here you didnt given you full code.The GetCaptureImage() function you are using
cp.image.SaveToMem(&Gl_buffer, &Gl_buflen, GX_BMP); //GX_JPEG. Here what is the cp.image with out getting the full information of the code you are using. I am unable to edit it. If it possible copy you full code here. What ever the example function i have given to you are windows APIs  and you are using other classes for you purpose .Either i have to have you classes or you have to use the function i have given to you. Because the image storage mechanisum of the classes you may be differ from windows APIs . I think you can use the code i have givin to you for solve you problem.That will work fine. Other ways you specify    
what are the classes you are using for the image manipulations in you application and i will try to solve it.

Regards,
Vimal Alex.

Reward 1Reward 2Reward 3Reward 4Reward 5Reward 6

EARN REWARDS FOR ASKING, ANSWERING, AND MORE.

Earn free swag for participating on the platform.


Hi Vimalalex,

I tryed with your code (please see in code //MEMORY VERSION) and that gives me well streaming of images, unfortunatly not the images that the camera saves but the images of my dialog view. So I think there is something to change to load the bmp image from the camera. I use too a function that can load from memory and which returns a HBITMAP, LoadBitmapFromMemory().

In the code  //FILE VERSION (commented code) is the version of application that works perfect but with files.

Please see code, you can see the old code that works well with file is commented. I added the code with memory version that display the dialog images but doesn't display bmp images from memory (Gl_buffer) into the picture box ?

Thank you

#include "Camdev.h" //this class is an wrapper class from GXImage class
 
//Globales
Camdev cp;
 
void *buffer = 0;
int buflen = 0;
 
RECT WndRect;
static HWND hWndImageRect;
static HDC	hdcDest;
 
HBITMAP eventsavedlgdc = (HBITMAP)::LoadImage(NULL,"readframes01.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
HDC           hMemDC;
RECT rectScaled;
int rectW;
int rectH;
 
 
 
 
// For time measuring
gxu64 fps_frametimems = 0;
gxu16 fps_frameix = 0;
gxu32 fps = 0;
gxu16 lastframeix = 0;	
 
// Waits for a captured frame
gxu16 status, newestframeix, nframes, nprocbufs, nusable, nlocked;
gxu64 newesttimems;
gxu16 nlockitems = 1;
FXCAM_FRAMEINFO lockitems[1];
bool CFXCAMd_ConfiguratorDlg::GetCaptureImage()
{
	try{
		while(1) {
					TRACE("While_new_frame_in");
					if(!cp.GetCaptureInfo(&status, &newestframeix, &newesttimems,
						&nframes, &nprocbufs, &nusable, &nlocked, lockitems, &nlockitems))
					{	
						gx_geterror(&ecode, ebuf, sizeof(ebuf));
						return TRUE;
					}
 
					if((status & 1) && (newestframeix != lastframeix)) {
						// OK, the frame buffer contains valid data
						break;	
					}
 
					#ifdef WIN32
					Sleep(10);
					#else
					usleep(10*1000);
					#endif
					TRACE("Not_valid_frame");
				}
		 
	}catch(...)
		{
		need_reconnect = true;
		}
		// Lock frame
		gxu64 frame;
		lastframeix = newestframeix;
		try{
 
		if(nlockitems == 0) {
			// No locked items
			frame = FXCAM_IX2FRAME(newestframeix);
			if(!cp.LockFrames(FXCAM_LOCK_RELEASE_ALL_OTHER, frame, frame)) {  //FXCAM_LOCK_ONLY_ONE_NEAREST FXCAM_LOCK_RELEASE_ALL_OTHER
				// Error occurred
				need_reconnect = true;
				return TRUE;
			}
 
		} else {
			// Found locked items
			frame = FXCAM_IX2FRAME(lockitems[0].index);
			newestframeix = lockitems[0].index;
			newesttimems = lockitems[0].timems;
			printf("\nTrigger event (timems: %llu, index: %u)\n", lockitems[0].timems, lockitems[0].index);
		}
		}catch(...)
		{
		need_reconnect = TRUE;
		}
		
		// Read frame
		gxu64 frametimems;
 		try 
		{
				DoEvents();
				if(!cp.ReadFrame(FXCAM_READFRAME_AUTOADJUST, 0, frame, NULL, &frametimems, &newestframeix, NULL, cp.image)) {
					if(nlockitems == 0) {
						// Error occurred
						need_reconnect = true;
						return TRUE;
					}
					MessageBox("cp.ReadFrame OK");
				}
		}
		catch(...)
		{	
			if(m_bStop)MessageBox("Exception From ReadFrame","Exception message"); //timer 2 generated
			need_reconnect = TRUE;
			return TRUE;
		}
 
		try 
		{	
				DoEvents();
				// Release the locked frame
				if(!cp.UnlockFrames(0, frame, frame)) {
					// Error occurred
					need_reconnect = true;
					return TRUE;
				}
			
		}
		catch(...)
		{	
			if(m_bStop)MessageBox("Exception From UnlockFrame","Exception message"); //timer 2 generated
			need_reconnect = TRUE;
			//SetTimer(1,80,0);
			return TRUE;
		}
 
				if(fps_frametimems+1000 < frametimems) {
					 fps = (gxu32)((1000*(frame-fps_frameix))/(frametimems-fps_frametimems));
					 fps_frametimems = frametimems;
					 fps_frameix = (gxu16)frame;
				}
	
		//FILE VERSION
		/*
		try{
		if(!cp.image.Save("readframes01.bmp", GX_BMP)) //Utiliser SavetoMem vers ppm (pour stream),  vers jpg (pour snapshot)
		{ 
			gx_geterror(&ecode, ebuf, sizeof(ebuf));
			MessageBox("Save image failed:.","Capture message");
			return TRUE;
		}
		}catch(...)
		{
		//MessageBox("ERROR IN cp.image.Save","trycatch message");
		need_reconnect = TRUE;
		}
		*/
 
		//MEMORY VERSION
	    try
		{
			cp.image.SaveToMem(&Gl_buffer, &Gl_buflen, GX_BMP); //GX_JPEG
		}
		catch(...)
		{
			 MessageBox("ERROR IN cp.image.SaveToMem","trycatch message");
		}
 
	return FALSE;
 
}
 
//------------------------------------------------------------------
// Load a DIB file from memory buffer.
// Return bitmap handle on success, NULL on error
//------------------------------------------------------------------
HBITMAP LoadBitmapFromMemory( void * pBmpFileData )
{
// Check parameter
ASSERT( pBmpFileData != NULL );
if ( pBmpFileData == NULL )
return NULL;
 
// Pointer to file bytes
BYTE * pFileBytes = (BYTE *)pBmpFileData;
 
// DIB bits (will be set by CreateDIBSection)
BYTE * pBits = NULL;
 
// Access the BITMAPINFOHEADER section
BITMAPINFOHEADER * pbmih = (BITMAPINFOHEADER *)(pFileBytes +
sizeof(BITMAPFILEHEADER));
 
// Create the DIB
HBITMAP hBitmap = ::CreateDIBSection(
NULL,                   // No HDC used
(BITMAPINFO *)pbmih,    // Pointer to DIB information
0,                      // Default
(void **)&pBits,        // The function will return pointer to
//   bitmap bits
NULL,                   // No file mapping
0 );                    // No file mapping
if ( hBitmap == NULL )
return NULL;
 
// Get pointer to bitmap bits in original file
// (we obtain the offset from BITMAPFILEHEADER.bfOffBits field)
BITMAPFILEHEADER * pbmfh = (BITMAPFILEHEADER *)pFileBytes;
BYTE * pSourceBitmapBits = pFileBytes + pbmfh->bfOffBits;
 
// Copy bits
memcpy(pBits, pSourceBitmapBits, pbmih->biSizeImage);
 
// Return bitmap handle
return hBitmap;
}
 
bool CFXCAMd_ConfiguratorDlg::DisplayImage() 
{
	  //FILE VERSION
/*
	  if (eventsavedlgdc)
	  { 
	    	::DeleteObject(eventsavedlgdc);
	  }
 
	  eventsavedlgdc = (HBITMAP)::LoadImage(NULL,"readframes01.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);  //BON
	  //eventsavedlgdc = ::LoadBitmapFromMemory( Gl_buffer );
 
 
	  CBitmap bmp;
	  bmp.Attach(eventsavedlgdc);
	  BITMAP bm;
	  bmp.GetBitmap(&bm);  
	  bmp.Detach(); 
 
	  HDC hdc=::GetDC(m_Picture.m_hWnd);
 
	  HDC memdc=::CreateCompatibleDC(hdc);
	  HBITMAP hBmp2=(HBITMAP)SelectObject(memdc,eventsavedlgdc);
  
	  SetStretchBltMode(hdc,COLORONCOLOR);  //For better quality
      StretchBlt(hdc,0,0,rectW,rectH,memdc,0,0,752,480,SRCCOPY); 
      DeleteDC(hdc);
      DeleteDC(memdc);
 
	  if(eventsavedlgdc)
	  {
 
			m_Picture.SetBitmap(hBmp2);
			DeleteDC(hMemDC);
			DeleteObject(eventsavedlgdc);
	  }
*/
 
 
 
      //MEMORY VERSION
	  HBITMAP hBitMap = ::LoadBitmapFromMemory( Gl_buffer );
 
	  RECT lp;
      BITMAPINFO OriginalInfo;
      unsigned char *OriginalBits;
      HDC hdc = ::GetWindowDC(m_hWnd);
      ::GetWindowRect(m_hWnd,&lp);
      HDC hdc1=::GetDC(m_hWnd);
      HDC memDC = CreateCompatibleDC ( hdc );
      hBitMap = ::CreateCompatibleBitmap(hdc,lp.right,lp.bottom);
 
      ::SelectObject ( memDC, hBitMap );  //eventsavedlgdc
      ::BitBlt(memDC,0,0,lp.right,lp.bottom,hdc,0,0,SRCCOPY);
      HGLOBAL hDIB =DDBToDIB(hBitMap, BI_RGB,&OriginalInfo,&OriginalBits );
      //WriteDIB("c:/temp.bmp",hDIB); //not to write on disk
      ::StretchDIBits(hdc1,0,40,OriginalInfo.bmiHeader.biWidth,OriginalInfo.bmiHeader.biHeight,0,0,OriginalInfo.bmiHeader.biWidth,OriginalInfo.bmiHeader.biHeight,OriginalBits,&OriginalInfo,DIB_RGB_COLORS,SRCCOPY);
      ::ReleaseDC(m_hWnd,hdc1);
      ::ReleaseDC(m_hWnd,hdc);
      ::GlobalFree(hDIB);
      ::DeleteObject(hBitMap);
 
	  return FALSE;
}
 
 
+++
 
	/** Saves an image in a specific file format to a specific memory area.
	 * @param buffer Pointer to the memory area pointer that is large enough or NULL.
	 * @param buflen Size of the memory area.
	 * @param fileformat Format of the image file (see \ref GX_IMGFILEFORMATS).
	 * @return An exception is thrown or false is returned in case of error. */
	inline bool SaveToMem(void **buffer, gxi32 *buflen, gxi32 fileformat) throw(gxError) {
		gxassert(_image);
		bool st = gx_savetomem(*this, _image, buffer, buflen, fileformat) ? true : false;
		gxcondthrow(!st);
		return st;
	}
	
/** Saves an image in a specific file format to a specific memory area.
 * @param handle Handle of the module.
 * @param pimage Pointer to the image.
 * @param buffer Pointer to the memory area pointer that is large enough or NULL.
 * @param buflen Size of the memory area.
 * @param fileformat Format of the image file (see \ref GX_IMGFILEFORMATS).
 * @return On error false is returned and the error code/string in the GX system
 *         is set appropriately ( see gx_geterror() ). */
inline gxi32 gx_savetomem(gxHANDLE handle, gxIMAGE* pimage,
					void **buffer, gxi32 *buflen, gxi32 fileformat) {
	struct GX_PARM_SAVETOMEM sm;
	assert(pimage);
	assert(buffer);
	assert(buflen);
	assert(*buflen >= 0);
	sm.pimage = pimage;
	sm.buffer = buffer;
	sm.buflen = buflen;
	sm.fileformat = fileformat;
	return gx_call(handle, GX_CALL_SAVETOMEM, (void *)&sm);
}
 
/** Calls a module process with the specified parameters.
 *
 * The functions and parameters usable inside the modules can be found in the
 * documentation of the modules. The headers given with the modules contain
 * inline functions, that make the access to the functions of the module easier.
 *
 * @see gx_openmodule() gx_closehandle() gx_direct()
 *
 * @param handle	Handle of an opened module or special system handle ( see gx_direct() ).
 * @param function	Identifier of the function (GX_CALL_xxx).
 * @param params	Parameters to give for the function (GX_PARM_xxx).
 * @return Module defined, usually non-zero on success. */
int GXAPI gx_call(struct gxHANDLE handle, int function, void *params) {
#ifdef WIN32
static gxldr_callfunc_t *gxsdldr_call = 0;
	if (!gxsdldr_call)
	{
		/* Call the init function if the gx_call() is not found */
		gxsdldr_init(&gxsdldr_call);
	}
#else
	if(!gxsdldr_call) gxsdldr_init();
#endif
	if (gxsdldr_call) return gxsdldr_call(handle, function, params);	/* GXSD library is loaded */
 
	/* GXSD library not loaded */
	switch(function) {
		case GX_CALL_GETERROR:	/* gx_geterror() function - Unicode mode */
			{
				if(params){
					struct GX_PARM_GETERROR *mp = (struct GX_PARM_GETERROR *)params;
					mp->code = ENOENT;
					if(mp->string && mp->maxlen>0) {
						gx_snwprintf(mp->string, mp->maxlen, L"gxsdldr: open error in %hs (%hs)",
							gxsdldr_modulename, gxsdldr_errstr);
						mp->string[mp->maxlen-1] = 0;
					}
				}
				return ENOENT;
			}
		case GX_CALL_GETERRORA:	/* gx_geterror() function - ASCII mode */
			{
				if(params){
					struct GX_PARM_GETERRORA *mp = (struct GX_PARM_GETERRORA *)params;
					mp->code = ENOENT;
					if(mp->string && mp->maxlen>0) {
						gx_snprintf(mp->string, mp->maxlen, "gxsdldr: open error in %s (%s)",
							gxsdldr_modulename, gxsdldr_errstr);
						mp->string[mp->maxlen-1] = 0;
					}
				}
				return ENOENT;
			}
		default:
			/* Unknown function */
			break;
	}
	
	/* Unknown function */
	errno = EINVAL;
	return 0;	
}

Open in new window


Hi Vimalalex,

Just remeber that after DisplayImage() function that I posted all functions that are called
for this call:

cp.image.SaveToMem(&Gl_buffer, &Gl_buflen, GX_BMP);

The Camdev class  is a wrapper class so there is severals calls.

But I think that there is something wrong in DisplayImage().

Thank you

HI Develprog,

                   In  bool CFXCAMd_ConfiguratorDlg::DisplayImage() you have written the code for displaying the window in you window which i have given is it working.

And Secondly i think you are trying to get the image from the web cam. Let me know one thing how you are capturing camera, are you capturing to any window and are you using DirectX or Windows APIs for capturing from camera.


Regards,
Vimal ALex

Free T-shirt

Get a FREE t-shirt when you ask your first question.

We believe in human intelligence. Our moderation policy strictly prohibits the use of LLM content in our Q&A threads.


ASKER CERTIFIED SOLUTION
Avatar of DevelprogDevelprog

ASKER

Link to home
membership
Log in or create a free account to see answer.
Signing up is free and takes 30 seconds. No credit card required.
Create Account

HI Develprog,
                      I think so you problem was solved.
Regards,
Vimal Alex

Hi Vimalalex, Hi Pqnatyuk,

Yes the problem is solved thank you both.


 



HI Develprog,
                     It is glade to hear that you problem solved.So accept any of the comments as your solution and close this question.

Regards,
Vimal Alex.

 

Reward 1Reward 2Reward 3Reward 4Reward 5Reward 6

EARN REWARDS FOR ASKING, ANSWERING, AND MORE.

Earn free swag for participating on the platform.

C++

C++

--

Questions

--

Followers

Top Experts

C++ is an intermediate-level general-purpose programming language, not to be confused with C or C#. It was developed as a set of extensions to the C programming language to improve type-safety and add support for automatic resource management, object-orientation, generic programming, and exception handling, among other features.