gpt4 book ai didi

C++ gdi::Bitmap 到内存中的 PNG 图像

转载 作者:太空宇宙 更新时间:2023-11-04 12:46:16 28 4
gpt4 key购买 nike

我正在尝试通过 tcp 将窗口的屏幕截图发送到服务器。获取屏幕截图没有问题(使用 GDIplus)。网络对我来说也很容易。问题是试图将 gdi+ 位图转换为 png(在内存中)以从中获取数据并将其发送到服务器。谁能帮帮我?

最佳答案

Gdiplus 可以保存到文件,或者使用IStream 保存到内存。参见 Gdiplus::Image::Save method

//get gdi+ bitmap
Gdiplus::Bitmap bitmap(hbitmap, nullptr);

//write to IStream
IStream* istream = nullptr;
HRESULT hr = CreateStreamOnHGlobal(NULL, TRUE, &istream);
CLSID clsid_png;
CLSIDFromString(L"{557cf406-1a04-11d3-9a73-0000f81ef32e}", &clsid_png);
bitmap.Save(istream, &clsid_png);

内存大小足够小,您可以从 IStream 复制到单个缓冲区(有关详细信息,请参阅“最小示例”)

//get memory handle associated with istream
HGLOBAL hg = NULL;
GetHGlobalFromStream(istream, &hg);

//copy IStream to buffer
int bufsize = GlobalSize(hg);
char *buffer = new char[bufsize];

//lock & unlock memory
LPVOID ptr = GlobalLock(hg);
memcpy(buffer, ptr, bufsize);
GlobalUnlock(hg);

//release will automatically free the memory allocated in CreateStreamOnHGlobal
istream->Release();

PNG 现在在 buffer 中可用,其大小为 bufsize。您可以直接使用二进制数据,或转换为 Base64 以通过网络发送。

最小示例:

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

bool save_png_memory(HBITMAP hbitmap, std::vector<BYTE>& data)
{
Gdiplus::Bitmap bmp(hbitmap, nullptr);

//write to IStream
IStream* istream = nullptr;
if (CreateStreamOnHGlobal(NULL, TRUE, &istream) != 0)
return false;

CLSID clsid_png;
if (CLSIDFromString(L"{557cf406-1a04-11d3-9a73-0000f81ef32e}", &clsid_png)!=0)
return false;
Gdiplus::Status status = bmp.Save(istream, &clsid_png);
if (status != Gdiplus::Status::Ok)
return false;

//get memory handle associated with istream
HGLOBAL hg = NULL;
if (GetHGlobalFromStream(istream, &hg) != S_OK)
return 0;

//copy IStream to buffer
int bufsize = GlobalSize(hg);
data.resize(bufsize);

//lock & unlock memory
LPVOID pimage = GlobalLock(hg);
if (!pimage)
return false;
memcpy(&data[0], pimage, bufsize);
GlobalUnlock(hg);

istream->Release();
return true;
}

int main()
{
CoInitialize(NULL);

ULONG_PTR token;
Gdiplus::GdiplusStartupInput tmp;
Gdiplus::GdiplusStartup(&token, &tmp, NULL);

//take screenshot
RECT rc;
GetClientRect(GetDesktopWindow(), &rc);
auto hdc = GetDC(0);
auto memdc = CreateCompatibleDC(hdc);
auto hbitmap = CreateCompatibleBitmap(hdc, rc.right, rc.bottom);
auto oldbmp = SelectObject(memdc, hbitmap);
BitBlt(memdc, 0, 0, rc.right, rc.bottom, hdc, 0, 0, SRCCOPY);
SelectObject(memdc, oldbmp);
DeleteDC(memdc);
ReleaseDC(0, hdc);

//save as png
std::vector<BYTE> data;
if(save_png_memory(hbitmap, data))
{
//write from memory to file for testing:
std::ofstream fout("test.png", std::ios::binary);
fout.write((char*)data.data(), data.size());
}
DeleteObject(hbitmap);

Gdiplus::GdiplusShutdown(token);
CoUninitialize();

return 0;
}

关于C++ gdi::Bitmap 到内存中的 PNG 图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51393621/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com