我在网上发现了这个代码来打印屏幕(截图),但我不知道如何修改它以将结果保存到PNG文件。
我可以将位图保存到剪贴板,但我现在需要保存到PNG文件。
到目前为止我的代码是:
#include <iostream>
#include <windows.h>
#include <gdiplus.h>
#include <stdexcept>
using namespace std;
using namespace Gdiplus;
using namespace Gdiplus::DllExports;
using std::runtime_error;
void screenshot(POINT a, POINT b)
{
HDC hScreen = GetDC(NULL);
HDC hDc = CreateCompatibleDC(hScreen);
HBITMAP hBitmap = CreateCompatibleBitmap(hScreen, abs(b.x-a.x), abs(b.y-a.y));
HGDIOBJ old_obj = SelectObject(hDc, hBitmap);
BOOL bRet = BitBlt(hDc, 0, 0, abs(b.x-a.y), abs(b.y-a.y), hScreen, a.x, a.y, SRCCOPY);
OpenClipboard(NULL);
EmptyClipboard();
SetClipboardData(CF_BITMAP, hBitmap);
CloseClipboard();
SelectObject(hDc, old_obj);
DeleteDC(hDc);
ReleaseDC(NULL, hScreen);
DeleteObject(hBitmap);
}
int main()
{
POINT a,b;
a.x=386;
a.y=749;
b.x=686;
b.y=1049;
screenshot(a,b);
}
链接 - https://causeyourestuck.io/2016/01/12/screenshot-c-win32-api/ 作者Omar AFLAK
答案 0 :(得分:2)
首先,包括Gdiplus的库。在Visual Studio中,您可以使用#pragam
关键字或在项目设置中添加Gdiplus.lib。
接下来,使用Gdiplus::GdiplusStartup
如前面所述找到编码器CLSID
。
在您的代码中,您有abs(b.x-a.y)
,大概应该是abs(b.x-a.x)
。如果a
应该是起点,则此逻辑可能不起作用。只需确保POINT b
大于POINT a
。或仔细阅读BitBlt
#include <Windows.h>
#include "gdiplus.h"
//Visual Studio shortcut for adding library:
#pragma comment(lib, "Gdiplus.lib")
int GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
{
UINT num = 0; // number of image encoders
UINT size = 0; // size of the image encoder array in bytes
Gdiplus::GetImageEncodersSize(&num, &size);
if(size == 0)
return -1; // Failure
Gdiplus::ImageCodecInfo* pImageCodecInfo = (Gdiplus::ImageCodecInfo*)(malloc(size));
if(pImageCodecInfo == NULL)
return -1; // Failure
GetImageEncoders(num, size, pImageCodecInfo);
for(UINT j = 0; j < num; ++j)
{
if(wcscmp(pImageCodecInfo[j].MimeType, format) == 0)
{
*pClsid = pImageCodecInfo[j].Clsid;
free(pImageCodecInfo);
return j; // Success
}
}
free(pImageCodecInfo);
return -1; // Failure
}
void screenshot(POINT a, POINT b)
{
int w = b.x - a.x;
int h = b.y - a.y;
if(w <= 0) return;
if(h <= 0) return;
HDC hScreen = GetDC(HWND_DESKTOP);
HDC hDc = CreateCompatibleDC(hScreen);
HBITMAP hBitmap = CreateCompatibleBitmap(hScreen, w, h);
HGDIOBJ old_obj = SelectObject(hDc, hBitmap);
BitBlt(hDc, 0, 0, w, h, hScreen, a.x, a.y, SRCCOPY);
Gdiplus::Bitmap bitmap(hBitmap, NULL);
CLSID clsid;
GetEncoderClsid(L"image/png", &clsid);
//GDI+ expects Unicode filenames
bitmap.Save(L"c:\\test\\test.png", &clsid);
SelectObject(hDc, old_obj);
DeleteDC(hDc);
ReleaseDC(HWND_DESKTOP, hScreen);
DeleteObject(hBitmap);
}
int main()
{
Gdiplus::GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
RECT rc;
GetClientRect(GetDesktopWindow(), &rc);
POINT a{ 0, 0 };
POINT b{ 100, 100 };
screenshot(a, b);
Gdiplus::GdiplusShutdown(gdiplusToken);
return 0;
}