C ++ save HBITMAP as a bitmap file

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);
	}
}

 

Guess you like

Origin www.cnblogs.com/xhubobo/p/12760051.html