C++gdi::内存中的位图到PNG图像
C++ gdi::Bitmap to PNG Image in memory
我正试图通过tcp向服务器发送一个窗口的屏幕截图。获取屏幕截图是没有问题的(使用GDIplus(。联网对我来说也很容易。问题是试图将gdi+位图转换为png(在内存中(,以从中获取数据并将其发送到服务器。有人能帮我吗?
Gdiplus可以保存到文件,也可以使用IStream
保存到内存。参见Gdiplus::图像::保存方法
//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;
}
相关文章:
- Qt-png图像未显示在部署应用程序中
- C++gdi::内存中的位图到PNG图像
- 当我调用它来解码 Blob 对象中的 png 图像时,"Magick++::readImages"引发警告
- 为什么PNG图像的stdout有时会在printf中刷新图像的一半
- 为嵌入式系统加载 png 图像
- OPENCV IMREAD 8BPP PNG图像错误
- OpenGL - SOIL 不会加载 JPG 或 PNG 图像
- 如何使用OPENCV C 将24位转换为8位深度PNG图像
- 如何使用GDI 显示具有25%不透明度的PNG图像?(MFC)
- 在窗口上绘制 PNG 图像 - C++ SDL 2.0
- .png图像信息
- 如何使用索引的 PNG 图像作为 SDL2/OpenGL 的纹理
- 使用 Allegro 5 加载.png图像文件
- 在 C 或 C++ 中将 JPEG 或 PNG 图像作为像素数据打开
- 为什么我的libharu pdf过大,带有.png图像
- png图像的大小
- 读取尺寸大于200x200像素的png图像时,0x77662D37(ntdll.dll)处出现未处理的异常
- 如何在boost::gil中使用alpha运河调整png图像的大小
- 在c++中嵌入PNG图像作为矢量或数组
- 使背景的QLabel png图像透明的设计时间