如何从 GDI 创建 Base64 编码的字符串? C++ 中的图像?
我最近问了一个问题,How can I create an Image in GDI+ from a Base64-Encoded string in C++?,它得到的响应引导我找到了答案。
现在我需要做相反的事情 - 我有一个 GDI+ 中的图像,我需要将其图像数据转换为 Base64 编码的字符串。由于其性质,它并不简单。
问题的关键在于 GDI+ 中的图像可以将其数据保存到文件或 IStream* 中。我不想保存到文件,所以我需要使用结果流。问题是,这就是我的知识崩溃的地方。
第一部分是我在另一个问题中想到的
// Initialize GDI+.
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
// I have this decode function from elsewhere
std::string decodedImage = base64_decode(Base64EncodedImage);
// Allocate the space for the stream
DWORD imageSize = decodedImage.length();
HGLOBAL hMem = ::GlobalAlloc(GMEM_MOVEABLE, imageSize);
LPVOID pImage = ::GlobalLock(hMem);
memcpy(pImage, decodedImage.c_str(), imageSize);
// Create the stream
IStream* pStream = NULL;
::CreateStreamOnHGlobal(hMem, FALSE, &pStream);
// Create the image from the stream
Image image(pStream);
// Cleanup
pStream->Release();
GlobalUnlock(hMem);
GlobalFree(hMem);
现在我将对生成的图像执行操作,在本例中是旋转它,现在完成后我需要 Base64 等效字符串。
// Perform operation (rotate)
image.RotateFlip(Gdiplus::Rotate180FlipNone);
IStream* oStream = NULL;
CLSID tiffClsid;
GetEncoderClsid(L"image/tiff", &tiffClsid); // Function defined elsewhere
image.Save(oStream, &tiffClsid);
// And here's where I'm stumped.
所以我结束了最后是一个 IStream* 对象。但这就是我的知识和谷歌对我来说都崩溃的地方。 IStream 本身不应该是一个对象,它是其他类型流的接口。我会沿着反向获取 string->Image 的道路,但我不知道如何确定流的大小,这似乎是该路线的关键。
如何从 IStream* 转换为字符串(然后对其进行 Base64 编码)?或者是否有更好的方法从 GDI+ 图像转换为字符串?
I asked a question recently, How can I create an Image in GDI+ from a Base64-Encoded string in C++?, which got a response that led me to the answer.
Now I need to do the opposite - I have an Image in GDI+ whose image data I need to turn into a Base64-Encoded string. Due to its nature, it's not straightforward.
The crux of the issue is that an Image in GDI+ can save out its data to either a file or an IStream*. I don't want to save to a file, so I need to use the resulting stream. Problem is, this is where my knowledge breaks down.
This first part is what I figured out in the other question
// Initialize GDI+.
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
// I have this decode function from elsewhere
std::string decodedImage = base64_decode(Base64EncodedImage);
// Allocate the space for the stream
DWORD imageSize = decodedImage.length();
HGLOBAL hMem = ::GlobalAlloc(GMEM_MOVEABLE, imageSize);
LPVOID pImage = ::GlobalLock(hMem);
memcpy(pImage, decodedImage.c_str(), imageSize);
// Create the stream
IStream* pStream = NULL;
::CreateStreamOnHGlobal(hMem, FALSE, &pStream);
// Create the image from the stream
Image image(pStream);
// Cleanup
pStream->Release();
GlobalUnlock(hMem);
GlobalFree(hMem);
And now I'm going to perform an operation on the resulting image, in this case rotating it, and now I want the Base64-equivalent string when I'm done.
// Perform operation (rotate)
image.RotateFlip(Gdiplus::Rotate180FlipNone);
IStream* oStream = NULL;
CLSID tiffClsid;
GetEncoderClsid(L"image/tiff", &tiffClsid); // Function defined elsewhere
image.Save(oStream, &tiffClsid);
// And here's where I'm stumped.
So what I wind up with at the end is an IStream* object. But here's where both my knowledge and Google break down for me. IStream shouldn't be an object itself, it's an interface for other types of streams. I'd go down the road from getting string->Image in reverse, but I don't know how to determine the size of the stream, which appears to be key to that route.
How can I go from an IStream* to a string (which I will then Base64-Encode)? Or is there a much better way to go from a GDI+ Image to a string?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
明白了
这个技巧,受到我从这篇文章中得到的启发,就是知道找出流大小的方法,并将其读入字符数组。然后我可以将该数组提供给
base64_encode
函数,瞧。Got it
The trick, as inspired by what I got from this article, is knowing the method to finding out the size of the stream, and having it read it into a character array. Then I can feed that array to the
base64_encode
function and voilà.