This article uses C ++ to save the bitmap handle HBITMAP as a bitmap file, and the C ++ capture code can be used to save the capture file (.bmp).
The steps are as follows:
1. Create a bitmap file;
2. Calculate the number of bytes occupied by each pixel in the
bitmap ; 3. Obtain the bitmap structure BITMAP;
4. Construct the bitmap information header BITMAPINFOHEADER;
5. Construct the bitmap file header BITMAPFILEHEADER;
6. Allocate memory for the content of the bitmap;
7. Process the palette;
8. Write to the file;
9. Clear resources.
The following is the C ++ source code:
ImageHelper.h
#pragma once #include <windows.h> #include <string> using namespace std; class ImageHelper { public: static bool SaveBitmapToFile (HBITMAP bitmap, const string & filename); // Save bitmap to file private: static WORD GetBitmapBitCount () ; // Calculate the number of bytes occupied by each pixel of the bitmap file static void ProcessPalette (HBITMAP hBitmap, const BITMAP & bitmap, DWORD paletteSize, LPBITMAPINFOHEADER lpBmpInfoHeader); // Process the palette };
ImageHelper.cpp
#include "ImageHelper.h" #include <shlwapi.h> bool ImageHelper :: SaveBitmapToFile (HBITMAP hBitmap, const string & filename) { // 1. Create bitmap file const auto file = CreateFileA (filename.c_str (), GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, nullptr); if (file == INVALID_HANDLE_VALUE) { return false; } // 2. Calculate the number of bytes per pixel in the bitmap file const auto bitCount = GetBitmapBitCount (); / / 3. Get bitmap structure BITMAP bitmap; :: GetObject (hBitmap, sizeof (bitmap), reinterpret_cast <LPSTR> (& bitmap)); // Pixel byte size in (32 bytes aligned) const DWORD bmBitsSize = ((bitmap.bmWidth * bitCount + 31) / 32) * 4 * bitmap.bmHeight; // Palette size const DWORD paletteSize = 0; // 4. Construct bitmap information header BITMAPINFOHEADER bmpInfoHeader; // Bitmap information header structure bmpInfoHeader.biSize = sizeof (BITMAPINFOHEADER); bmpInfoHeader.biWidth = bitmap.bmWidth; bmpInfoHeader. biHeight = bitmap.bmHeight; bmpInfoHeader.biPlanes = 1; bmpInfoHeader.biBitCount = bitCount; bmpInfoHeader.biCompression = BI_RGB; bmpInfoHeader.biSizeImage = 0; bmpInfoHeader.biXPelsPerMeter = 0; bmpInfoHeader.biYPelsPerMeter = 0; bmpInfoHeader; 0 . biClrUsed = 0; // 5. Construct the bitmap file header BITMAPFILEHEADER bmpFileHeader; bmpFileHeader.bfType = 0x4D42; // "BM" // Bitmap file size const DWORD dibSize = sizeof (BITMAPFILEHEADER) + sizeof (BITMAPINFOHEADER) + paletteSize + bmBitsSize; bmpFileHeader.bfSize = dibSize; bmpFileHeader.bfReserved1 = 0; bmpFileHeader.bfReserved2 = 0; bmpFileHeader ( boffFileDer ( BoffFileHeader) BITMAPFILEHEADER)) + static_cast <DWORD> (sizeof (BITMAPINFOHEADER)) + paletteSize; // 6. Allocate memory for bitmap content const auto dib = GlobalAlloc (GHND, bmBitsSize + paletteSize + sizeof (BITMAPINFOHEADER)); // Memory handle const auto lpBmpInfoHeader = static_cast <LPBITMAPINFOHEADER> (GlobalLock (dib)); // Point to the bitmap information header structure * lpBmpInfoHeader = bmpInfoHeader; // 7. Process palette ProcessPalette (hBitmap, bitmap, paletteSize, lpBmpInfoHeader); // 8. Write to file DWORD written = 0; // Number of bytes written to the file WriteFile (file, reinterpret_cast <LPSTR> (& bmpFileHeader), sizeof (BITMAPFILEHEADER), & written, nullptr); // Write to the bitmap file header WriteFile (file, reinterpret_cast <LPSTR > (lpBmpInfoHeader), dibSize, & written, nullptr); // Write the rest of the bitmap file // 9. Clean up resources GlobalUnlock (dib); GlobalFree (dib); CloseHandle (file); return true; } // Calculate the bit The number of bytes per pixel in the image file WORD ImageHelper :: GetBitmapBitCount () { const auto dc = :: CreateDCA ("DISPLAY", nullptr, nullptr, nullptr); // Number of bytes per pixel at the current resolution const auto bits = :: GetDeviceCaps (dc, BITSPIXEL) * GetDeviceCaps (dc, PLANES); :: DeleteDC (dc); // Number of bytes per pixel in the bitmap WORD bitCount; if (bits <= 1) bitCount = 1; else if (bits <= 4) bitCount = 4; else if (bits <= 8) bitCount = 8; else bitCount = 24; return bitCount; } // Process palette void ImageHelper :: ProcessPalette (HBITMAP hBitmap, const the BITMAP & Bitmap, DWORD paletteSize, LPBITMAPINFOHEADER lpBmpInfoHeader) { HANDLE = nullptr a oldPalette; the HDC = nullptr a DC; const = Auto palette the GetStockObject (DEFAULT_PALETTE); IF (! = nullptr a palette) { dc = :: GetDC (nullptr); oldPalette = ::SelectPalette(dc, static_cast<HPALETTE>(palette), FALSE); :: RealizePalette (dc); // Realize the device palette } // Get new pixel values under this palette GetDIBits(dc, hBitmap, 0, static_cast<UINT>(bitmap.bmHeight), reinterpret_cast<LPSTR>(lpBmpInfoHeader) + sizeof(BITMAPINFOHEADER) + paletteSize, reinterpret_cast<BITMAPINFO*>(lpBmpInfoHeader), DIB_RGB_COLORS); //恢复调色板 if (oldPalette != nullptr) { ::SelectPalette(dc, static_cast<HPALETTE>(oldPalette), TRUE); ::RealizePalette(dc); ::ReleaseDC(nullptr, dc); } }