我想拍摄PNG
格式的屏幕截图。但是我有一个严重的问题,我认为这对教授来说似乎很容易。1。如何从位图(类)获取图像缓冲区。2.我使用的是多显示器,分辨率也不同。如何获得全屏分辨率。
实现:
#pragma comment (lib, "gdiplus.lib")
#include "stdafx.h"
#include <afxwin.h>
#include <stdio.h>
#include <tchar.h>
#include <gdiplus.h>
using namespace Gdiplus;
DWORD PNGScreenshot();
INT GetEncoderClsid(const WCHAR * format, CLSID* pClsid);
INT GetEncoderClsid(const WCHAR * format, CLSID* pClsid)
{
UINT num = 0;
UINT size = 0;
ImageCodecInfo* pImageCodecInfo = NULL;
GetImageEncodersSize(&num, &size);
if (size == 0)
return -1;
pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
if (pImageCodecInfo == NULL)
return -1;
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;
}
}
free(pImageCodecInfo);
return -1;
}
DWORD PNGScreenshot()
{
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
HDC hScreenDC = CreateDC(L"DISPLAY", NULL, NULL, NULL);
HDC hMemoryDC = CreateCompatibleDC(hScreenDC);
INT x = GetDeviceCaps(hScreenDC, HORZRES);
INT y = GetDeviceCaps(hScreenDC, VERTRES);
HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, x, y);
HBITMAP hOldBitmap = (HBITMAP)SelectObject(hMemoryDC, hBitmap);
StretchBlt(hMemoryDC, 0, 0, x, y, hScreenDC, 0, 0, x, y, SRCCOPY);
hBitmap = (HBITMAP)SelectObject(hMemoryDC, hOldBitmap);
CLSID pngClsid;
GetEncoderClsid(L"image/png", &pngClsid);
Bitmap *bmp = new Bitmap(hBitmap, NULL);
// Get Image Buffer from Bitmap
// GetBufferFromBitmap(LPBYTE lpImageBuffer, Bitmap * bmp);
// {
// 1. Get Size of Bitmap
// 2. Get Image buffer from Bitmap
// 3. Copy Image buffer to lpImageBuffer
// }
// ... Do ...
delete bmp;
GdiplusShutdown(gdiplusToken);
return GetLastError();
}
int _tmain(int argc, _TCHAR* argv[])
{
PNGScreenshot();
return 0;
}
这只是我的实现,那么还有其他方法可以将PNG屏幕快照用作缓冲区吗?
一个替代实现可能是使用IStream接口。使用Save方法使用IStream
编解码器将位图存储到clsid_png
对象,然后返回到图像FromStream。 @Barmak的MCVE使用memcpy
而不是FromStream
。