把位图保存为文件源代码
最近想写一个截图工具,就研究了一下位图的结构。下面代码是把位图以BMP文件的结构写入文件中的。
#include <Windows.h> BOOL SaveBitmapToFile(LPCTSTR lpszFilePath, HBITMAP hBm) { // 定义位图文件表头 BITMAPFILEHEADER bmfh; // 定义位图信息表头 BITMAPINFOHEADER bmih; // 调色板长度 int nColorLen = 0; // 调色表大小 DWORD dwRgbQuadSize = 0; // 位图大小 DWORD dwBmSize = 0; // 分配内存的指针 HGLOBAL hMem = NULL; LPBITMAPINFOHEADER lpbi; BITMAP bm;
HDC hDC; HANDLE hFile = NULL; DWORD dwWritten; GetObject(hBm, sizeof(BITMAP), &bm); bmih.biSize = sizeof(BITMAPINFOHEADER); // 本结构所占的字节 bmih.biWidth = bm.bmWidth; // 位图宽 bmih.biHeight = bm.bmHeight; // 位图高 bmih.biPlanes = 1; bmih.biBitCount = bm.bmBitsPixel; // 每一图素的位数 bmih.biCompression = BI_RGB; // 不压缩 bmih.biSizeImage = 0; // 位图大小 bmih.biXPelsPerMeter = 0; bmih.biYPelsPerMeter = 0; bmih.biClrUsed = 0; bmih.biClrImportant = 0; // 计算位图图素数据区大小 dwBmSize = 4 * ((bm.bmWidth * bmih.biBitCount + 31) / 32) * bm.bmHeight; // 如果图素位 <= 8bit,则有调色板 if (bmih.biBitCount <= 8) { nColorLen = (1 << bm.bmBitsPixel); } // 计算调色板大小 dwRgbQuadSize = nColorLen * sizeof(RGBQUAD); // 分配内存 hMem = GlobalAlloc(GHND, dwBmSize + dwRgbQuadSize + sizeof(BITMAPINFOHEADER)); if (NULL == hMem) { return FALSE; } // 锁定内存 lpbi = (LPBITMAPINFOHEADER)GlobalLock(hMem); // 将bmih中的内容写入分配的内存中 *lpbi = bmih;
hDC= GetDC(NULL);
// 将位图中的数据以bits的形式放入lpData中。 GetDIBits(hDC, hBm, 0, (DWORD)bmih.biHeight, (LPSTR)lpbi+sizeof(BITMAPINFOHEADER)+dwRgbQuadSize, (BITMAPINFO *)lpbi, (DWORD)DIB_RGB_COLORS); bmfh.bfType = 0x4D42; // 位图文件类型:BM bmfh.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwRgbQuadSize + dwBmSize; // 位图大小 bmfh.bfReserved1 = 0; bmfh.bfReserved2 = 0; bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwRgbQuadSize; // 位图数据与文件头部的偏移量 // 把上面的数据写入文件中 hFile = CreateFile(lpszFilePath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN, NULL); if (INVALID_HANDLE_VALUE == hFile) { return FALSE; } // 写入位图文件头 WriteFile(hFile, (LPSTR)&bmfh, sizeof(BITMAPFILEHEADER), (DWORD *)&dwWritten, NULL); // 写入位图数据 WriteFile(hFile, (LPBITMAPINFOHEADER)lpbi, bmfh.bfSize - sizeof(BITMAPFILEHEADER), (DWORD *)&dwWritten, NULL); GlobalFree(hMem); CloseHandle(hFile); return TRUE; }