Tôi đang làm việc với một bộ khung và cần lấy hình ảnh từ bộ nhớ máy tính và lưu chúng vào một tệp hình ảnh. sau khi thử vài ngày, tôi kết thúc với 2 chức năng sau, điều này tạo ra một tệp và cửa sổ OS có thể chạy tệp .bmp, nhưng tệp bitmap là màu đen (kích thước hình ảnh là 900KB, 640 * 480). không có bất kỳ cơ thể có bất kỳ ý tưởng tại sao, hình ảnh màu đen? đây là hai chức năng:C Win32: lưu hình ảnh .bmp từ HBITMAP
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
}
và đây là chức năng để lưu vào .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;
}
TÔI CÓ THỂ Vẽ các hình ảnh từ bộ nhớ hoàn hảo với các chức năng sau đây, vì vậy chắc chắn Tôi không có bất kỳ vấn đề cho việc đọc dữ liệu hình ảnh:
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);
}
Tôi không thay đổi gì trong DrawPicture(); chức năng – user261002