将内存位图写入到BMP文件中

这是一个用于将内存中的HBITMAP对象转换并写入到BMP文件的C++函数。它获取位图的颜色格式、宽度、高度,根据颜色位数创建BITMAPINFO结构,并将位图数据写入文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

// 从将内存位图句柄(HBITMAP)写入到BMP文件中

// 返回 非零表示成功写入

// 参数 LPCTSTR 文件名

// 参数 HBITMAP 内存位图句柄

BOOL CreateBMPFileFromBitmapObject(LPCTSTR szFileName, HBITMAP hBitmap)

{

BITMAPFILEHEADER hdr;              // bitmap file-header 

BITMAP bmp;

PBITMAPINFOHEADER pbih = NULL;     // bitmap info-header 

PBITMAPINFO pbmi = NULL; 

LPBYTE lpBits = NULL;             // memory pointer 

DWORD dwTotal;                    // total count of bytes 

DWORD dwTmp; 

HANDLE hFile = NULL;

HDC hdc = NULL;

WORD cClrBits;

BOOL bSuccess = FALSE;

 

if(hBitmap == NULL || szFileName == NULL)

return FALSE;

 

// Retrieve the bitmap color format, width, and height. 

if (!::GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bmp))

return FALSE;

 

// Convert the color format to a count of bits. 

cClrBits = (WORD)(bmp.bmPlanes * bmp.bmBitsPixel); 

if (cClrBits == 1) cClrBits = 1; 

else if (cClrBits <= 4) cClrBits = 4; 

else if (cClrBits <= 8) cClrBits = 8; 

else if (cClrBits <= 16) cClrBits = 16; 

else if (cClrBits <= 24) cClrBits = 24; 

else cClrBits = 32; 

 

// Allocate memory for the BITMAPINFO structure. (This structure 

// contains a BITMAPINFOHEADER structure and an array of RGBQUAD 

// data structures.) 

//if (cClrBits != 24) 

if (cClrBits < 24) // 防止在64位机下的出错

{

pbmi = (PBITMAPINFO) LocalAlloc(LPTR, 

sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (1<< cClrBits)); 

}

else 

{

// There is no RGBQUAD array for the 24-bit-per-pixel format. 

pbmi = (PBITMAPINFO) LocalAlloc(LPTR, sizeof(BITMAPINFOHEADER)); 

}

 

if(pbmi == NULL)

goto end;

 

// Initialize the fields in the BITMAPINFO structure. 

 

pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 

pbmi->bmiHeader.biWidth = bmp.bmWidth; 

pbmi->bmiHeader.biHeight = bmp.bmHeight; 

pbmi->bmiHeader.biPlanes = bmp.bmPlanes; 

pbmi->bmiHeader.biBitCount = bmp.bmBitsPixel; 

if (cClrBits < 24) 

pbmi->bmiHeader.biClrUsed = (1<<cClrBits); 

 

// If the bitmap is not compressed, set the BI_RGB flag. 

pbmi->bmiHeader.biCompression = BI_RGB; 

 

// Compute the number of bytes in the array of color 

// indices and store the result in biSizeImage. 

// For Windows NT, the width must be DWORD aligned unless 

// the bitmap is RLE compressed. This example shows this. 

// For Windows 95/98/Me, the width must be WORD aligned unless the 

// bitmap is RLE compressed.

pbmi->bmiHeader.biSizeImage = ((pbmi->bmiHeader.biWidth * cClrBits +31) & ~31) /8

* pbmi->bmiHeader.biHeight; 

// Set biClrImportant to 0, indicating that all of the 

// device colors are important. 

pbmi->bmiHeader.biClrImportant = 0; 

 

 

hdc = GetDC(NULL);

 

pbih = (PBITMAPINFOHEADER) pbmi; 

lpBits = (LPBYTE) ::GlobalAlloc(GMEM_FIXED, pbih->biSizeImage);

if(lpBits == NULL)

goto end;

 

// Retrieve the color table (RGBQUAD array) and the bits 

// (array of palette indices) from the DIB. 

if (!GetDIBits(hdc, hBitmap, 0, (WORD) pbih->biHeight, lpBits, pbmi, DIB_RGB_COLORS)) 

goto end;

 

// Create the .BMP file. 

hFile = CreateFile(szFileName, 

GENERIC_READ | GENERIC_WRITE, 

(DWORD) 0, 

NULL, 

CREATE_ALWAYS, 

FILE_ATTRIBUTE_NORMAL, 

(HANDLE) NULL); 

if (hFile == INVALID_HANDLE_VALUE) 

goto end; 

 

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(hFile, (LPVOID) &hdr, sizeof(BITMAPFILEHEADER), (LPDWORD) &dwTmp, NULL)) 

goto end; 

 

// Copy the BITMAPINFOHEADER and RGBQUAD array into the file. 

if (!WriteFile(hFile, (LPVOID) pbih, 

sizeof(BITMAPINFOHEADER) + pbih->biClrUsed * sizeof (RGBQUAD), 

(LPDWORD) &dwTmp, ( NULL))

goto end;

 

// Copy the array of color indices into the .BMP file. 

dwTotal = pbih->biSizeImage; 

if (!WriteFile(hFile, (LPVOID) lpBits, (int) dwTotal, (LPDWORD) &dwTmp,NULL)) 

goto end;

 

bSuccess = TRUE;

 

end:;

// Close the .BMP file. 

if(hFile != NULL)

CloseHandle(hFile);

if(pbmi != NULL)

LocalFree((HLOCAL)pbmi);

// Free memory. 

if(lpBits != NULL)

GlobalFree((HGLOBAL)lpBits);

if(hdc != NULL)

ReleaseDC(NULL, hdc);

return bSuccess;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值