保存HBITMAP只使用Win32的为* .bmp文件 [英] Save HBITMAP to *.bmp file using only Win32
问题描述
我在我的纯粹的Win32项目HBITMAP(无外部库使用)。我可以只使用WINAPI和/或CRT函数,所以我不承担任何额外的依赖将其导出为* .bmp文件?
I have a HBITMAP in my pure Win32 project (no external libraries are used). Can I export it to a *.bmp file using only Winapi and/or CRT functions so I don't incur any extra dependencies?
推荐答案
有没有API来保存到文件中直接原因,一般有一个位图处理,并不意味着你必须为位图数据的直接访问。解决方案是将位图复制到与数据存取(DIB),然后用它的数据写入到文件中的另一个位图。
There is no API to save into file directly because, generally, having a bitmap handle does not mean you have direct access to bitmap data. Your solution is to copy bitmap into another bitmap with data access (DIB) and then using it data to write into file.
您通常可以创建使用另一个位图 CreateDIBSection
或你与的GetDIBits
位图数据。
You typically either create another bitmap using CreateDIBSection
, or you get bitmap data with GetDIBits
.
的CreateFile
, WriteFile的
将数据写入到文件中。
CreateFile
, WriteFile
writes data into file.
您写的: BITMAPFILEHEADER
,那么 BITMAPINFOHEADER
,然后调色板(你通常不必当比特/像素是超过8),那么数据本身。
You write: BITMAPFILEHEADER
, then BITMAPINFOHEADER
, then palette (which you typically don't have when bits/pixel is over 8), then data itself.
另请参阅:
- C++: Hbitmap/BITMAP into .bmp file (this answer)
- Saving .bmp file using hBitmap = CreateDIBSection() in C Win32
- Storing an Image on MSDN
这是从MSDN的文章(注意您需要定义 errhandler()
功能)code:
This is the code from the MSDN article (Note that you need to define the errhandler()
function):
PBITMAPINFO CreateBitmapInfoStruct(HWND hwnd, HBITMAP hBmp)
{
BITMAP bmp;
PBITMAPINFO pbmi;
WORD cClrBits;
// Retrieve the bitmap color format, width, and height.
if (!GetObject(hBmp, sizeof(BITMAP), (LPSTR)&bmp))
errhandler("GetObject", hwnd);
// 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)
pbmi = (PBITMAPINFO) LocalAlloc(LPTR,
sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD) * (1<< cClrBits));
// There is no RGBQUAD array for these formats: 24-bit-per-pixel or 32-bit-per-pixel
else
pbmi = (PBITMAPINFO) LocalAlloc(LPTR,
sizeof(BITMAPINFOHEADER));
// 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.
// The width must be DWORD 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;
return pbmi;
}
void CreateBMPFile(HWND hwnd, LPTSTR pszFile, PBITMAPINFO pbi,
HBITMAP hBMP, HDC hDC)
{
HANDLE hf; // file handle
BITMAPFILEHEADER hdr; // bitmap file-header
PBITMAPINFOHEADER pbih; // bitmap info-header
LPBYTE lpBits; // memory pointer
DWORD dwTotal; // total count of bytes
DWORD cb; // incremental count of bytes
BYTE *hp; // byte pointer
DWORD dwTmp;
pbih = (PBITMAPINFOHEADER) pbi;
lpBits = (LPBYTE) GlobalAlloc(GMEM_FIXED, pbih->biSizeImage);
if (!lpBits)
errhandler("GlobalAlloc", hwnd);
// Retrieve the color table (RGBQUAD array) and the bits
// (array of palette indices) from the DIB.
if (!GetDIBits(hDC, hBMP, 0, (WORD) pbih->biHeight, lpBits, pbi,
DIB_RGB_COLORS))
{
errhandler("GetDIBits", hwnd);
}
// Create the .BMP file.
hf = CreateFile(pszFile,
GENERIC_READ | GENERIC_WRITE,
(DWORD) 0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
(HANDLE) NULL);
if (hf == INVALID_HANDLE_VALUE)
errhandler("CreateFile", hwnd);
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(hf, (LPVOID) &hdr, sizeof(BITMAPFILEHEADER),
(LPDWORD) &dwTmp, NULL))
{
errhandler("WriteFile", hwnd);
}
// Copy the BITMAPINFOHEADER and RGBQUAD array into the file.
if (!WriteFile(hf, (LPVOID) pbih, sizeof(BITMAPINFOHEADER)
+ pbih->biClrUsed * sizeof (RGBQUAD),
(LPDWORD) &dwTmp, ( NULL)))
errhandler("WriteFile", hwnd);
// Copy the array of color indices into the .BMP file.
dwTotal = cb = pbih->biSizeImage;
hp = lpBits;
if (!WriteFile(hf, (LPSTR) hp, (int) cb, (LPDWORD) &dwTmp,NULL))
errhandler("WriteFile", hwnd);
// Close the .BMP file.
if (!CloseHandle(hf))
errhandler("CloseHandle", hwnd);
// Free memory.
GlobalFree((HGLOBAL)lpBits);
}
这篇关于保存HBITMAP只使用Win32的为* .bmp文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!