gpt4 book ai didi

C Win32 : save . 来自 HBITMAP 的 bmp 图像

转载 作者:太空狗 更新时间:2023-10-29 16:44:28 24 4
gpt4 key购买 nike

我正在使用图像采集卡,需要从计算机内存中获取图像并将它们保存在图像文件中。在尝试了几天后,我最终得到了以下 2 个函数,它创建了一个文件并且 Windows 操作系统能够运行 .bmp 文件,但是位图文件是黑色的(图像大小为 900KB,640*480)。有没有人知道为什么图片是黑色的?这是两个函数:

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
}

这里是保存到 .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;
}

我可以使用以下函数完美地从内存中绘制图像,所以我可以肯定地读取图像数据没有任何问题:

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 );

}

最佳答案

我刚刚发现我使用的代码的另一部分有一个愚蠢的错误:

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

通过删除 hBitmap2 = CreateCompatibleBitmap (hDCBits, lXSize, lYSize); 行,并将 hBitmap2 更改为 hBitmap 作为 CreateDIBSection() 的结果,它保存了精美的图像。感谢大家的帮助。

关于C Win32 : save . 来自 HBITMAP 的 bmp 图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9586915/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com