c++ gdiplus实现屏幕截图

发布时间 2023-05-17 13:45:12作者: My_opt
#include <windows.h>
#include <gdiplus.h>
#include <iostream>
#include <filesystem>
#include <chrono>
#include <iomanip>
#include <sstream>

#pragma comment(lib, "Gdiplus.lib") using namespace Gdiplus; ULONG_PTR gdiplusToken; std::wstring StringToWstring(const std::string& s) { int len; int slength = (int)s.length() + 1; len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0); wchar_t* buf = new wchar_t[len]; MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len); std::wstring r(buf); delete[] buf; return r; } 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 ImageCodecInfo* pImageCodecInfo = NULL; GetImageEncodersSize(&num, &size); if (size == 0) return -1; // Failure pImageCodecInfo = (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 SaveScreenshot(std::string filename, ULONG uQuality = 100) { ULONG_PTR gdiplusToken; GdiplusStartupInput gdiplusStartupInput; GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); HDC scrdc, memdc; HBITMAP membit; scrdc = ::GetDC(0); int Height = GetSystemMetrics(SM_CYSCREEN); int Width = GetSystemMetrics(SM_CXSCREEN); memdc = CreateCompatibleDC(scrdc); membit = CreateCompatibleBitmap(scrdc, Width, Height); HBITMAP hOldBitmap = (HBITMAP)SelectObject(memdc, membit); BitBlt(memdc, 0, 0, Width, Height, scrdc, 0, 0, SRCCOPY); Gdiplus::Bitmap bitmap(membit, NULL); CLSID clsid; int ret = GetEncoderClsid(L"image/png", &clsid); if (ret != -1) { std::wstring wfilename = StringToWstring(filename); bitmap.Save(wfilename.c_str(), &clsid); } SelectObject(memdc, hOldBitmap); DeleteObject(memdc); DeleteObject(membit); ::ReleaseDC(0, scrdc); GdiplusShutdown(gdiplusToken); } std::string GetCurrentTimeStr() { auto now = std::chrono::system_clock::now(); auto in_time_t = std::chrono::system_clock::to_time_t(now); std::tm timeinfo; localtime_s(&timeinfo, &in_time_t); std::stringstream ss; ss << std::put_time(&timeinfo, "%Y-%m-%d-%H-%M-%S"); return ss.str(); } int main() { GdiplusStartupInput gdiplusStartupInput; GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); std::string filename = "tmp/" + GetCurrentTimeStr() + ".png"; std::filesystem::create_directories("tmp"); SaveScreenshot(filename); GdiplusShutdown(gdiplusToken); return 0; }