Ç的Win32:拯救HBITMAP .BMP图像 [英] C Win32: save .bmp image from HBITMAP
问题描述
我用图像采集工作,需要从电脑存储器中的影像并将其保存到一个图像文件。尝试了几天后,我结束了以下2个功能,它创建了一个文件和Windows操作系统能够运行.bmp文件,但位图文件是黑色(图像尺寸为900KB,640 * 480)。做任何机构有任何想法,为什么,画面为黑色?
这里有两个功能:
LPSTR CreateBMP(HWND hAppWnd,诠释nImageType)
{
无效* pWinGBits = NULL;
INT I;
Z_BITMAPINFO zWinGHeader; //为BITMAPINFO的cerating DIB
//位图创建DC。
hDCBits = CreateCompatibleDC(ghDCMain); 开关(nImageType)
{
案例bayer_filter:
zWinGHeader.bmiHeader.biSize = sizeof的(BITMAPINFOHEADER);
zWinGHeader.bmiHeader.biPlanes = 1;
zWinGHeader.bmiHeader.biClrImportant = 0;
zWinGHeader.bmiHeader.biHeight = -lYSize;
zWinGHeader.bmiHeader.biWidth = lXSize;
zWinGHeader.bmiHeader.biBitCount = 32;
zWinGHeader.bmiHeader.biClrUsed = 0; // 3;
zWinGHeader.bmiHeader.biCom pression = BI_BITFIELDS;
zWinGHeader.bmiHeader.biSizeImage = 0;
zWinGHeader.bmiColors [0] .rgbBlue = 0×00;
zWinGHeader.bmiColors [0] .rgbGreen = 0×00;
zWinGHeader.bmiColors [0] .rgbRed = 0xFF的;
zWinGHeader.bmiColors [0] .rgbReserved = 0×00; zWinGHeader.bmiColors [1] .rgbBlue = 0×00;
zWinGHeader.bmiColors [1] .rgbGreen = 0xFF的;
zWinGHeader.bmiColors [1] .rgbRed = 0×00;
zWinGHeader.bmiColors [1] .rgbReserved = 0×00; zWinGHeader.bmiColors [2] .rgbBlue = 0xFF的;
zWinGHeader.bmiColors [2] .rgbGreen = 0×00;
zWinGHeader.bmiColors [2] .rgbRed = 0×00;
zWinGHeader.bmiColors [2] .rgbReserved = 0×00;
打破; 案例color32:
zWinGHeader.bmiHeader.biSize = sizeof的(BITMAPINFOHEADER);
zWinGHeader.bmiHeader.biPlanes = 1;
zWinGHeader.bmiHeader.biClrImportant = 0;
zWinGHeader.bmiHeader.biHeight = -lYSize;
zWinGHeader.bmiHeader.biWidth = lXSize / 4;
zWinGHeader.bmiHeader.biBitCount = 32;
zWinGHeader.bmiHeader.biClrUsed = 0;
zWinGHeader.bmiHeader.biCom pression = BI_BITFIELDS;
zWinGHeader.bmiHeader.biSizeImage = 0;
zWinGHeader.bmiColors [0] .rgbBlue = 0×00;
zWinGHeader.bmiColors [0] .rgbGreen = 0×00;
zWinGHeader.bmiColors [0] .rgbRed = 0xFF的;
zWinGHeader.bmiColors [0] .rgbReserved = 0×00; zWinGHeader.bmiColors [1] .rgbBlue = 0×00;
zWinGHeader.bmiColors [1] .rgbGreen = 0xFF的;
zWinGHeader.bmiColors [1] .rgbRed = 0×00;
zWinGHeader.bmiColors [1] .rgbReserved = 0×00; zWinGHeader.bmiColors [2] .rgbBlue = 0xFF的;
zWinGHeader.bmiColors [2] .rgbGreen = 0×00;
zWinGHeader.bmiColors [2] .rgbRed = 0×00;
zWinGHeader.bmiColors [2] .rgbReserved = 0×00;
打破; 案例color24:
zWinGHeader.bmiHeader.biSize = sizeof的(BITMAPINFOHEADER);
zWinGHeader.bmiHeader.biPlanes = 1;
zWinGHeader.bmiHeader.biClrImportant = 0;
zWinGHeader.bmiHeader.biHeight = -lYSize;
zWinGHeader.bmiHeader.biWidth = lXSize / 3;
zWinGHeader.bmiHeader.biBitCount = 24;
zWinGHeader.bmiHeader.biClrUsed = 0;
zWinGHeader.bmiHeader.biCom pression = BI_RGB;
zWinGHeader.bmiHeader.biSizeImage = 0;
打破; 案例color3x16:
zWinGHeader.bmiHeader.biSize = sizeof的(BITMAPINFOHEADER);
zWinGHeader.bmiHeader.biPlanes = 1;
zWinGHeader.bmiHeader.biClrImportant = 0;
zWinGHeader.bmiHeader.biHeight = -lYSize;
zWinGHeader.bmiHeader.biWidth = lXSize / 6;
zWinGHeader.bmiHeader.biBitCount = 32;
zWinGHeader.bmiHeader.biClrUsed = 0;
zWinGHeader.bmiHeader.biCom pression = BI_BITFIELDS;
zWinGHeader.bmiHeader.biSizeImage = 0;
zWinGHeader.bmiColors [0] .rgbBlue = 0×00;
zWinGHeader.bmiColors [0] .rgbGreen = 0×00;
zWinGHeader.bmiColors [0] .rgbRed = 0xFF的;
zWinGHeader.bmiColors [0] .rgbReserved = 0×00; zWinGHeader.bmiColors [1] .rgbBlue = 0×00;
zWinGHeader.bmiColors [1] .rgbGreen = 0xFF的;
zWinGHeader.bmiColors [1] .rgbRed = 0×00;
zWinGHeader.bmiColors [1] .rgbReserved = 0×00; zWinGHeader.bmiColors [2] .rgbBlue = 0xFF的;
zWinGHeader.bmiColors [2] .rgbGreen = 0×00;
zWinGHeader.bmiColors [2] .rgbRed = 0×00;
zWinGHeader.bmiColors [2] .rgbReserved = 0×00;
打破; 案例bw1x10:
//创建位图infoheader。
zWinGHeader.bmiHeader.biSize = sizeof的(BITMAPINFOHEADER);
zWinGHeader.bmiHeader.biPlanes = 1;
zWinGHeader.bmiHeader.biBitCount = 8;
zWinGHeader.bmiHeader.biCom pression = BI_RGB;
zWinGHeader.bmiHeader.biSizeImage = 0;
zWinGHeader.bmiHeader.biClrUsed = 256;
zWinGHeader.bmiHeader.biClrImportant = 0;
zWinGHeader.bmiHeader.biHeight = -lYSize;
zWinGHeader.bmiHeader.biWidth = lXSize / 2; //创建colortable FOT位图(grayvalues)。
对于(i = 0; I< 256;我++)
{
zWinGHeader.bmiColors [I] .rgbGreen = I;
zWinGHeader.bmiColors [I] .rgbBlue = I;
zWinGHeader.bmiColors [I] .rgbRed = I; zWinGHeader.bmiColors [I] .rgbReserved = 0;
}
打破; 默认:
案例bw8:
//创建位图infoheader。
zWinGHeader.bmiHeader.biSize = sizeof的(BITMAPINFOHEADER);
zWinGHeader.bmiHeader.biPlanes = 1;
zWinGHeader.bmiHeader.biBitCount = 8;
zWinGHeader.bmiHeader.biCom pression = BI_RGB;
zWinGHeader.bmiHeader.biSizeImage = 0;
zWinGHeader.bmiHeader.biClrUsed =(1 <<;&下; 8);
zWinGHeader.bmiHeader.biClrImportant = 0;
zWinGHeader.bmiHeader.biHeight = -lYSize;
zWinGHeader.bmiHeader.biWidth = lXSize;
//zWinGHeader.bmiHeader.biSizeImage =((zWinGHeader.bmiHeader.biWidth * 8 +31)及〜31)/ 8
// * zWinGHeader.bmiHeader.biHeight; //创建colortable FOT位图(grayvalues)。
对于(i = 0; I&LT; 256;我++)
{
zWinGHeader.bmiColors [I] .rgbGreen = I;
zWinGHeader.bmiColors [I] .rgbBlue = I;
zWinGHeader.bmiColors [I] .rgbRed = I;
zWinGHeader.bmiColors [I] .rgbReserved = 0;
}
打破;
} //创造学习的身份调色板
HPAL = CreateIdentityPalette(zWinGHeader.bmiColors); //获取新的调色板成直流和映射到物理调色板寄存器。
hOldPal = SelectPalette(ghDCMain,HPAL,FALSE);
RealizePalette(ghDCMain); //创造学习DIB-F节黵图像数据的直接访问。
HBITMAP = CreateDIBSection(
hDCBits,//设备上下文句柄
(BITMAPINFO *)及zWinGHeader,//含有结构的地址
//位图大小,格式和彩色数据
DIB_RGB_COLORS,//颜色数据类型指示:RGB值
//或调色板索引
&安培; pWinGBits,//指针变量接收一个指针
//位图的位值
NULL,//可选句柄文件映射对象
0 //偏移中的位图位值
//文件映射对象
);
//获取位图到DC。
hOldBitmap =(HBITMAP)选择对象(hDCBits,HBITMAP); 返回pWinGBits; //返回指针DIB
}
和这里的函数保存到.BMP:
BOOL的SaveToFile(HBITMAP hBitmap3,LPCTSTR lpszFileName)
{
HDC的hDC;
INT iBits;
WORD wBitCount;
DWORD dwPaletteSize = 0,dwBmBitsSize = 0,dwDIBSize = 0,dwWritten = 0;
位图Bitmap0;
BITMAPFILEHEADER bmfHdr;
BITMAPINFOHEADER双向;
LPBITMAPINFOHEADER LPBI;
手柄FH,hDib,HPAL,hOldPal2 = NULL;
的hDC =的CreateDC(DISPLAY,NULL,NULL,NULL);
iBits = GetDeviceCaps(HDC,BITSPIXEL)* GetDeviceCaps(HDC,飞机);
DeleteDC(HDC);
如果(iBits&下; = 1)
wBitCount = 1;
否则如果(iBits&下; = 4)
wBitCount = 4;
否则如果(iBits&下; = 8)
wBitCount = 8;
其他
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.biCom pression = 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 =双向; HPAL = GetStockObject(DEFAULT_PALETTE);
如果(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); 如果(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); 如果(FH == INVALID_HANDLE_VALUE)
返回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);
计数器= 1;
返回TRUE;
}
我可以得出从内存中的图像完美地与下面的函数,所以可以肯定我没有任何问题,用于读取图像数据:
无效DrawPicture(HDC的hDC,PBYTE pDest,PBYTE PSRC,LONG lXSize,LONG lYSize)
{
LONG lXSizeDiv,lYSizeDiv;
龙LX,LY;
DWORD dwMax;
RECT RECT;
HDC HDC;
PBYTE pTmpDest;
双fXFactor,fYFactor;
// HBRUSH HBRUSH;
//点对点;
开关(gzMvfgKamDef.iImageType)
{
案例bayer_filter:
lXSizeDiv = 1;
lYSizeDiv = 1;
BayerToRGB((PDWORD)pDest,PSRC,lXSize,lYSize,
gzMvfgKamDef.iBayerQuadrant,gzMvfgKamDef.iBayerQuality); 打破; 案例color24:
lXSizeDiv = 3;
lYSizeDiv = 1;
的memcpy(pDest,PSRC,(为size_t)(lXSize * lYSize));打破; 案例color32:
lXSizeDiv = 4;
lYSizeDiv = 1;
的memcpy(pDest,PSRC,(为size_t)(lXSize * lYSize));
打破; 案例color3x16:
lXSizeDiv = 6;
lYSizeDiv = 1;
Conv3x16To3x8(pDest,PSRC,4,lXSize,lYSize);
打破; 案例bw1x10:
lXSizeDiv = 2;
lYSizeDiv = 1;
Conv1x10To1x8(pDest,PSRC,2,lXSize,lYSize);
打破; 案例bw6Tap:
lXSizeDiv = 1;
lYSizeDiv = 1;
Conv6TapTo1x8(pDest,PSRC,1,lXSize,lYSize); 打破; 默认:
案例bw8:
lXSizeDiv = 1;
lYSizeDiv = 1;
的memcpy(pDest,PSRC,(为size_t)(lXSize * lYSize)); 打破;}
如果(gahIniDlg [NdxHistogramDlg] .hWnd)
{
memset的(gadwHistogram,0,sizeof的(gadwHistogram)); pTmpDest = pDest; 对于(LY = 0; LY&LT; lYSize; LY ++)
{
为(LX = 0; LX&下; lXSize; LX ++)
{
gadwHistogram [* pTmpDest] ++;
pTmpDest ++;
}
} GetClientRect(gahIniDlg [NdxHistogramDlg] .hWnd,&安培; RECT); HDC =的GetDC(gahIniDlg [NdxHistogramDlg] .hWnd); dwMax = 0;
为(LX = 0; LX&下; = 0xff的; LX ++)
dwMax =(gadwHistogram [LX]&GT; dwMax)? gadwHistogram [LX]:dwMax; fYFactor =(双)dwMax /(双)rect.bottom;
fXFactor =(双)(rect.right - 100)/(双)为0x100;/ *
选择对象(HDC,GetStockObject(BLACK_PEN)); 对于(LX = 0; LX和LT = 0xFF的; LX + = 8)
{
MoveToEx(HDC,LX * fXFactor,rect.bottom,&安培;点);
的LineTo(HDC,LX * fXFactor,rect.bottom-10);
}
* /
选择对象(HDC,GetStockObject(WHITE_PEN));// HBRUSH = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
// HBRUSH = CreateSolidBrush(0XFFFFFF);
//选择对象(HDC,HBRUSH);
折线(HDC,gaHistogram中,0x100);// DeleteObject的(HBRUSH); 为(LX = 0; LX&下; = 0xff的; LX ++)
{
gaHistogram [LX] .X =(DWORD)(fXFactor *(双)LX);
gaHistogram [LX] .Y = rect.bottom - (DWORD)((双)gadwHistogram [LX] / fYFactor);
} 选择对象(HDC,GetStockObject(BLACK_PEN)); 折线(HDC,gaHistogram中,0x100); ReleaseDC(gahIniDlg [NdxHistogramDlg] .hWnd,HDC);
}//显示位图
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);}
我刚刚发现我在code的另一部分我是用了愚蠢的错误:
//转换图像以位图和显示它
DrawPicture(ghDCMain,pWinGBitmap,gpbImageData,lXSize,lYSize);
如果(计数器!= 1){
hBitmap2 = CreateCompatibleBitmap(hDCBits,lXSize,lYSize);
的SaveToFile(hBitmap2,C:\\\\ t.bmp);
OutputDebugString的(测试!!!!);
}
通过删除 hBitmap2 = CreateCompatibleBitmap(hDCBits,lXSize,lYSize);
行,并改变hBitmap2到HBITMAP CreateDIBSection()的结果,它精美保存图像。谢谢大家的帮助。
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 :
LPSTR CreateBMP( HWND hAppWnd, int nImageType )
{
void * pWinGBits = NULL;
int i;
Z_BITMAPINFO zWinGHeader; // bitmapinfo for cerating the DIB
// create DC for bitmap.
hDCBits = CreateCompatibleDC( ghDCMain );
switch ( nImageType )
{
case bayer_filter:
zWinGHeader.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
zWinGHeader.bmiHeader.biPlanes = 1;
zWinGHeader.bmiHeader.biClrImportant = 0;
zWinGHeader.bmiHeader.biHeight = -lYSize;
zWinGHeader.bmiHeader.biWidth = lXSize;
zWinGHeader.bmiHeader.biBitCount = 32;
zWinGHeader.bmiHeader.biClrUsed = 0;//3;
zWinGHeader.bmiHeader.biCompression = BI_BITFIELDS;
zWinGHeader.bmiHeader.biSizeImage = 0;
zWinGHeader.bmiColors[0].rgbBlue = 0x00;
zWinGHeader.bmiColors[0].rgbGreen = 0x00;
zWinGHeader.bmiColors[0].rgbRed = 0xFF;
zWinGHeader.bmiColors[0].rgbReserved = 0x00;
zWinGHeader.bmiColors[1].rgbBlue = 0x00;
zWinGHeader.bmiColors[1].rgbGreen = 0xFF;
zWinGHeader.bmiColors[1].rgbRed = 0x00;
zWinGHeader.bmiColors[1].rgbReserved = 0x00;
zWinGHeader.bmiColors[2].rgbBlue = 0xFF;
zWinGHeader.bmiColors[2].rgbGreen = 0x00;
zWinGHeader.bmiColors[2].rgbRed = 0x00;
zWinGHeader.bmiColors[2].rgbReserved = 0x00;
break;
case color32:
zWinGHeader.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
zWinGHeader.bmiHeader.biPlanes = 1;
zWinGHeader.bmiHeader.biClrImportant = 0;
zWinGHeader.bmiHeader.biHeight = -lYSize;
zWinGHeader.bmiHeader.biWidth = lXSize/4;
zWinGHeader.bmiHeader.biBitCount = 32;
zWinGHeader.bmiHeader.biClrUsed = 0;
zWinGHeader.bmiHeader.biCompression = BI_BITFIELDS;
zWinGHeader.bmiHeader.biSizeImage = 0;
zWinGHeader.bmiColors[0].rgbBlue = 0x00;
zWinGHeader.bmiColors[0].rgbGreen = 0x00;
zWinGHeader.bmiColors[0].rgbRed = 0xFF;
zWinGHeader.bmiColors[0].rgbReserved = 0x00;
zWinGHeader.bmiColors[1].rgbBlue = 0x00;
zWinGHeader.bmiColors[1].rgbGreen = 0xFF;
zWinGHeader.bmiColors[1].rgbRed = 0x00;
zWinGHeader.bmiColors[1].rgbReserved = 0x00;
zWinGHeader.bmiColors[2].rgbBlue = 0xFF;
zWinGHeader.bmiColors[2].rgbGreen = 0x00;
zWinGHeader.bmiColors[2].rgbRed = 0x00;
zWinGHeader.bmiColors[2].rgbReserved = 0x00;
break;
case color24:
zWinGHeader.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
zWinGHeader.bmiHeader.biPlanes = 1;
zWinGHeader.bmiHeader.biClrImportant = 0;
zWinGHeader.bmiHeader.biHeight = -lYSize;
zWinGHeader.bmiHeader.biWidth = lXSize/3;
zWinGHeader.bmiHeader.biBitCount = 24;
zWinGHeader.bmiHeader.biClrUsed = 0;
zWinGHeader.bmiHeader.biCompression = BI_RGB;
zWinGHeader.bmiHeader.biSizeImage = 0;
break;
case color3x16:
zWinGHeader.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
zWinGHeader.bmiHeader.biPlanes = 1;
zWinGHeader.bmiHeader.biClrImportant = 0;
zWinGHeader.bmiHeader.biHeight = -lYSize;
zWinGHeader.bmiHeader.biWidth = lXSize/6;
zWinGHeader.bmiHeader.biBitCount = 32;
zWinGHeader.bmiHeader.biClrUsed = 0;
zWinGHeader.bmiHeader.biCompression = BI_BITFIELDS;
zWinGHeader.bmiHeader.biSizeImage = 0;
zWinGHeader.bmiColors[0].rgbBlue = 0x00;
zWinGHeader.bmiColors[0].rgbGreen = 0x00;
zWinGHeader.bmiColors[0].rgbRed = 0xFF;
zWinGHeader.bmiColors[0].rgbReserved = 0x00;
zWinGHeader.bmiColors[1].rgbBlue = 0x00;
zWinGHeader.bmiColors[1].rgbGreen = 0xFF;
zWinGHeader.bmiColors[1].rgbRed = 0x00;
zWinGHeader.bmiColors[1].rgbReserved = 0x00;
zWinGHeader.bmiColors[2].rgbBlue = 0xFF;
zWinGHeader.bmiColors[2].rgbGreen = 0x00;
zWinGHeader.bmiColors[2].rgbRed = 0x00;
zWinGHeader.bmiColors[2].rgbReserved = 0x00;
break;
case bw1x10:
// create bitmap-infoheader.
zWinGHeader.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
zWinGHeader.bmiHeader.biPlanes = 1;
zWinGHeader.bmiHeader.biBitCount = 8;
zWinGHeader.bmiHeader.biCompression = BI_RGB;
zWinGHeader.bmiHeader.biSizeImage = 0;
zWinGHeader.bmiHeader.biClrUsed = 256;
zWinGHeader.bmiHeader.biClrImportant= 0;
zWinGHeader.bmiHeader.biHeight = -lYSize;
zWinGHeader.bmiHeader.biWidth = lXSize/2;
// create colortable fot bitmap (grayvalues).
for (i = 0; i < 256; i++)
{
zWinGHeader.bmiColors[i].rgbGreen = i;
zWinGHeader.bmiColors[i].rgbBlue = i;
zWinGHeader.bmiColors[i].rgbRed = i;
zWinGHeader.bmiColors[i].rgbReserved = 0;
}
break;
default:
case bw8:
// create bitmap-infoheader.
zWinGHeader.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
zWinGHeader.bmiHeader.biPlanes = 1;
zWinGHeader.bmiHeader.biBitCount = 8;
zWinGHeader.bmiHeader.biCompression = BI_RGB;
zWinGHeader.bmiHeader.biSizeImage = 0;
zWinGHeader.bmiHeader.biClrUsed = (1<<8);
zWinGHeader.bmiHeader.biClrImportant= 0;
zWinGHeader.bmiHeader.biHeight = -lYSize;
zWinGHeader.bmiHeader.biWidth = lXSize;
//zWinGHeader.bmiHeader.biSizeImage = ((zWinGHeader.bmiHeader.biWidth * 8 +31) & ~31) /8
// * zWinGHeader.bmiHeader.biHeight;
// create colortable fot bitmap (grayvalues).
for (i = 0; i < 256; i++)
{
zWinGHeader.bmiColors[i].rgbGreen = i;
zWinGHeader.bmiColors[i].rgbBlue = i;
zWinGHeader.bmiColors[i].rgbRed = i;
zWinGHeader.bmiColors[i].rgbReserved = 0;
}
break;
}
// cerate identity palette
hPal = CreateIdentityPalette( zWinGHeader.bmiColors );
// get new palette into DC and map into physical palette register.
hOldPal = SelectPalette( ghDCMain, hPal, FALSE);
RealizePalette( ghDCMain );
// cerate DIB-Section f黵 direct access of image-data.
hBitmap = CreateDIBSection(
hDCBits, // handle of device context
(BITMAPINFO *)&zWinGHeader, // address of structure containing
// bitmap size, format and color data
DIB_RGB_COLORS, // color data type indicator: RGB values
// or palette indices
&pWinGBits, // pointer to variable to receive a pointer
// to the bitmap's bit values
NULL, // optional handle to a file mapping object
0 // offset to the bitmap bit values within
// the file mapping object
);
// get bitmap into DC .
hOldBitmap = (HBITMAP)SelectObject( hDCBits, hBitmap );
return pWinGBits; // return pointer to DIB
}
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 );
}
I just find out I had a silly mistake in another part of my code I was using :
// Convert Image to bitmap and display it
DrawPicture( ghDCMain, pWinGBitmap, gpbImageData, lXSize, lYSize );
if(counter!=1) {
hBitmap2 = CreateCompatibleBitmap (hDCBits, lXSize, lYSize);
SaveToFile(hBitmap2, "c:\\t.bmp");
OutputDebugString("tested !!!!");
}
by deleting the hBitmap2 = CreateCompatibleBitmap (hDCBits, lXSize, lYSize);
line, and changing the hBitmap2 to hBitmap the result of CreateDIBSection(), it saved the image beautifully. THANK YOU EVERYONE FOR YOUR HELP.
这篇关于Ç的Win32:拯救HBITMAP .BMP图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!