有什么方法可以使用ofstream保存屏幕截图吗?

时间:2019-11-29 08:10:54

标签: c++ windows

我正在尝试捕获屏幕截图,然后将其另存为bmp文件。

为什么保存文件后我的程序无法运行?

我将信息放入文件中,并将其保存在项目所在的位置,但是当我打开文件时,什么也没有出现。

我会很感激。

编辑:我已经更新了代码,但是仍然无法正常工作,当我打开文件时,什么也没有出现。

#include <iostream>
#include <Windows.h>
#include <fstream>

using namespace std;

int width = GetSystemMetrics(SM_CXSCREEN);
int height = GetSystemMetrics(SM_CYSCREEN);

string deskdir = "C:\\Users\\roile\\Desktop\\";

void screenshot()
{
    HDC     hScreen = GetDC(GetDesktopWindow());
    HBITMAP hBitmap = CreateCompatibleBitmap(hScreen, width, height);

    ofstream image;
    image.open(deskdir + "Image.bmp", ios::binary);
    image << hBitmap;
    image.close();
}

int main()
{
    screenshot();

    return 0;
}

1 个答案:

答案 0 :(得分:0)

HBITMAP是一个句柄。它类似于指针,基本上是一个整数值,它指向由OS管理的存储位置图的存储位置。此句柄仅对您自己的进程可用,进程存在后立即销毁。

您必须从此HBITMAP句柄中提取位图信息和位。

请注意,完成后必须释放GDI句柄,否则程序会导致资源泄漏。

void screenshot()
{
    SetProcessDPIAware();//for DPI awreness
    RECT rc; GetClientRect(GetDesktopWindow(), &rc);
    int width = rc.right;
    int height = rc.bottom;
    auto hdc = GetDC(0);
    auto memdc = CreateCompatibleDC(hdc);
    auto hbitmap = CreateCompatibleBitmap(hdc, width, height);
    auto oldbmp = SelectObject(memdc, hbitmap);
    BitBlt(memdc, 0, 0, width, height, hdc, 0, 0, SRCCOPY);

    WORD bpp = 24; //save as 24bit image
    int size = ((width * bpp + 31) / 32) * 4 * height; //adjust for padding
    BYTE *bits = new BYTE[size]; //you can use std::vector instead of new to prevent leaks

    BITMAPFILEHEADER bf = { 0 };
    bf.bfType = (WORD)'MB';
    bf.bfOffBits = 54;
    bf.bfSize = bf.bfOffBits + size;
    BITMAPINFOHEADER bi = { sizeof(bi), width, height, 1, bpp };
    GetDIBits(hdc, hbitmap, 0, height, bits, (BITMAPINFO*)&bi, 0);

    std::ofstream image("Image.bmp", ios::binary);
    image.write((char*)&bf, sizeof(bf));
    image.write((char*)&bi, sizeof(bi));
    image.write((char*)bits, size);

    delete[] bits;
    SelectObject(memdc, oldbmp);
    DeleteObject(hbitmap);
    DeleteDC(memdc);
    ReleaseDC(0, hdc);
}