#include <Windows.h>
#include <iostream>
using namespace std;
// 保存bmp文件
void saveBMPFile(const char* filename, void* pBmp, int width, int height)
{
HANDLE hFile = CreateFileA(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == NULL)
{
return;
}
// 已写入字节数
DWORD bytesWritten = 0;
// 位图大小
int bmpSize = width * height * 4;
// 文件头
BITMAPFILEHEADER bmpHeader;
// 文件总大小 = 文件头 + 位图信息头 + 位图数据
bmpHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + bmpSize;
// 固定
bmpHeader.bfType = 0x4D42;
// 数据偏移,即位图数据所在位置
bmpHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
// 保留为0
bmpHeader.bfReserved1 = 0;
// 保留为0
bmpHeader.bfReserved2 = 0;
// 写文件头
WriteFile(hFile, (LPSTR)&bmpHeader, sizeof(bmpHeader), &bytesWritten, NULL);
// 位图信息头
BITMAPINFOHEADER bmiHeader;
// 位图信息头大小
bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
// 位图像素宽度
bmiHeader.biWidth = width;
// 位图像素高度
bmiHeader.biHeight = height;
// 必须为1
bmiHeader.biPlanes = 1;
// 像素所占位数
bmiHeader.biBitCount = 32;
// 0表示不压缩
bmiHeader.biCompression = 0;
// 位图数据大小
bmiHeader.biSizeImage = bmpSize;
// 水平分辨率(像素/米)
bmiHeader.biXPelsPerMeter = 0;
// 垂直分辨率(像素/米)
bmiHeader.biYPelsPerMeter = 0;
// 使用的颜色,0为使用全部颜色
bmiHeader.biClrUsed = 0;
// 重要的颜色数,0为所有颜色都重要
bmiHeader.biClrImportant = 0;
// 写位图信息头
WriteFile(hFile, (LPSTR)&bmiHeader, sizeof(bmiHeader), &bytesWritten, NULL);
// 写位图数据
WriteFile(hFile, pBmp, bmpSize, &bytesWritten, NULL);
CloseHandle(hFile);
}
int main()
{
// 获取屏幕dc
HDC hdcScreen = GetDC(NULL);
// 创建内存dc
HDC hdcMemDC = CreateCompatibleDC(hdcScreen);
// 获取hdcScreen中的宽高,也就是屏幕像素的宽高
int desktopWidth = GetDeviceCaps(hdcScreen, HORZRES);
int desktopHeight = GetDeviceCaps(hdcScreen, VERTRES);
BITMAPINFO bi;
// 注意一定要设置如下的头部信息,否则rgb指针将始终为NULL
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bi.bmiHeader.biWidth = desktopWidth;
bi.bmiHeader.biHeight = desktopHeight;
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biBitCount = 32;
bi.bmiHeader.biCompression = BI_RGB;
bi.bmiHeader.biSizeImage = desktopWidth * desktopHeight * 4;
// 存放图像数据指针
byte* rgb = NULL;
// 创建与设备无关的位图
HBITMAP hbitmap = CreateDIBSection(hdcScreen, &bi, DIB_RGB_COLORS, (void**)&rgb, NULL, 0);
SelectObject(hdcMemDC, hbitmap);
// 复制屏幕数据
BitBlt(hdcMemDC, 0, 0, desktopWidth, desktopHeight, hdcScreen, 0, 0, SRCCOPY | CAPTUREBLT);
// 保存bmp位图文件
saveBMPFile("test.bmp", rgb, desktopWidth, desktopHeight);
// 释放相关对象
DeleteDC(hdcMemDC);
ReleaseDC(NULL, hdcScreen);
return 0;
}
参考文献
https://docs.microsoft.com/en-us/previous-versions/dd183376(v=vs.85)