I am working with a framegrabber and need to get the images from computer memory and save them on an image file. after trying for couple of days I end up with the following 2 functions, which creates a file and windows OS is able to run the .bmp file, but the bitmap file is black (the image size is 900KB , 640*480). does any body has any idea why, the picture is in black? here are the two functions :
and here is the function for saving into .bmp :
BOOL SaveToFile(HBITMAP hBitmap3, LPCTSTR lpszFileName) { HDC hDC; int iBits; WORD wBitCount; DWORD dwPaletteSize=0, dwBmBitsSize=0, dwDIBSize=0, dwWritten=0; BITMAP Bitmap0; BITMAPFILEHEADER bmfHdr; BITMAPINFOHEADER bi; LPBITMAPINFOHEADER lpbi; HANDLE fh, hDib, hPal,hOldPal2=NULL; hDC = CreateDC("DISPLAY", NULL, NULL, NULL); iBits = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES); DeleteDC(hDC); if (iBits <= 1) wBitCount = 1; else if (iBits <= 4) wBitCount = 4; else if (iBits <= 8) wBitCount = 8; else wBitCount = 24; GetObject(hBitmap3, sizeof(Bitmap0), (LPSTR)&Bitmap0); bi.biSize = sizeof(BITMAPINFOHEADER); bi.biWidth = Bitmap0.bmWidth; bi.biHeight =-Bitmap0.bmHeight; bi.biPlanes = 1; bi.biBitCount = wBitCount; bi.biCompression = BI_RGB; bi.biSizeImage = 0; bi.biXPelsPerMeter = 0; bi.biYPelsPerMeter = 0; bi.biClrImportant = 0; bi.biClrUsed = 256; dwBmBitsSize = ((Bitmap0.bmWidth * wBitCount +31) & ~31) /8 * Bitmap0.bmHeight; hDib = GlobalAlloc(GHND,dwBmBitsSize + dwPaletteSize + sizeof(BITMAPINFOHEADER)); lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib); *lpbi = bi; hPal = GetStockObject(DEFAULT_PALETTE); if (hPal) { hDC = GetDC(NULL); hOldPal2 = SelectPalette(hDC, (HPALETTE)hPal, FALSE); RealizePalette(hDC); } GetDIBits(hDC, hBitmap3, 0, (UINT) Bitmap0.bmHeight, (LPSTR)lpbi + sizeof(BITMAPINFOHEADER) +dwPaletteSize, (BITMAPINFO *)lpbi, DIB_RGB_COLORS); if (hOldPal2) { SelectPalette(hDC, (HPALETTE)hOldPal2, TRUE); RealizePalette(hDC); ReleaseDC(NULL, hDC); } fh = CreateFile(lpszFileName, GENERIC_WRITE,0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); if (fh == INVALID_HANDLE_VALUE) return FALSE; bmfHdr.bfType = 0x4D42; // "BM" dwDIBSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwPaletteSize + dwBmBitsSize; bmfHdr.bfSize = dwDIBSize; bmfHdr.bfReserved1 = 0; bmfHdr.bfReserved2 = 0; bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER) + dwPaletteSize; WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL); WriteFile(fh, (LPSTR)lpbi, dwDIBSize, &dwWritten, NULL); GlobalUnlock(hDib); GlobalFree(hDib); CloseHandle(fh); counter=1; return TRUE; }
I CAN Draw the images from memory perfectly with the following function, so for sure I dont have any problem for reading the image data :
void DrawPicture( HDC hDC, PBYTE pDest, PBYTE pSrc, LONG lXSize, LONG lYSize ) { LONG lXSizeDiv, lYSizeDiv; LONG lX, lY; DWORD dwMax; RECT rect; HDC hdc; PBYTE pTmpDest; double fXFactor, fYFactor; // HBRUSH hBrush; // POINT Point; switch( gzMvfgKamDef.iImageType ) { case bayer_filter: lXSizeDiv = 1; lYSizeDiv = 1; BayerToRGB( (PDWORD) pDest, pSrc, lXSize, lYSize, gzMvfgKamDef.iBayerQuadrant, gzMvfgKamDef.iBayerQuality ); break; case color24: lXSizeDiv = 3; lYSizeDiv = 1; memcpy( pDest, pSrc, (size_t)( lXSize * lYSize ) ); break; case color32: lXSizeDiv = 4; lYSizeDiv = 1; memcpy( pDest, pSrc, (size_t)( lXSize * lYSize ) ); break; case color3x16: lXSizeDiv = 6; lYSizeDiv = 1; Conv3x16To3x8( pDest, pSrc, 4, lXSize, lYSize ); break; case bw1x10: lXSizeDiv = 2; lYSizeDiv = 1; Conv1x10To1x8( pDest, pSrc, 2, lXSize, lYSize ); break; case bw6Tap: lXSizeDiv = 1; lYSizeDiv = 1; Conv6TapTo1x8( pDest, pSrc, 1, lXSize, lYSize ); break; default: case bw8: lXSizeDiv = 1; lYSizeDiv = 1; memcpy( pDest, pSrc, (size_t)( lXSize * lYSize ) ); break; } if( gahIniDlg[ NdxHistogramDlg ].hWnd ) { memset( gadwHistogram, 0, sizeof( gadwHistogram) ); pTmpDest = pDest; for ( lY = 0; lY < lYSize; lY++ ) { for ( lX = 0; lX < lXSize; lX++ ) { gadwHistogram[ *pTmpDest ]++; pTmpDest++; } } GetClientRect ( gahIniDlg[ NdxHistogramDlg ].hWnd, &rect) ; hdc = GetDC ( gahIniDlg[ NdxHistogramDlg ].hWnd ); dwMax = 0; for ( lX = 0 ; lX <= 0xff; lX++ ) dwMax = ( gadwHistogram[ lX ] > dwMax ) ? gadwHistogram[ lX ] : dwMax; fYFactor = (double) dwMax / (double) rect.bottom; fXFactor = (double) ( rect.right - 100 ) / (double) 0x100; /* SelectObject (hdc, GetStockObject (BLACK_PEN)) ; for( lX = 0; lX <= 0xff; lX+=8 ) { MoveToEx( hdc, lX * fXFactor, rect.bottom, &Point ); LineTo( hdc, lX * fXFactor, rect.bottom-10 ); } */ SelectObject (hdc, GetStockObject (WHITE_PEN)) ; // hBrush = CreateSolidBrush( GetSysColor( COLOR_WINDOW )); // hBrush = CreateSolidBrush( 0xffffff ); // SelectObject (hdc, hBrush); Polyline( hdc, gaHistogram, 0x100 ); // DeleteObject( hBrush ); for ( lX = 0 ; lX <= 0xff; lX++ ) { gaHistogram[ lX ].x = (DWORD)( fXFactor * (double)lX ); gaHistogram[ lX ].y = rect.bottom - (DWORD)( (double) gadwHistogram[ lX ] / fYFactor ); } SelectObject (hdc, GetStockObject (BLACK_PEN)) ; Polyline( hdc, gaHistogram, 0x100 ); ReleaseDC ( gahIniDlg[ NdxHistogramDlg ].hWnd , hdc ) ; } // display the bitmap StretchBlt( hDC, rcWin.left, rcWin.top, lXSize / lXSizeDiv, lYSize / lYSizeDiv, hDCBits, 0, 0, lXSize / lXSizeDiv, lYSize / lYSizeDiv, SRCCOPY ); //BitBlt( hDC, rcWin.left, rcWin.top, lXSize / lXSizeDiv, lYSize / lYSizeDiv, //hDCBits, 0, 0, SRCCOPY ); }