GDI截取桌面图像

#include 
#include 

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)

你可能感兴趣的:(GDI截取桌面图像)