如何从 C++ 中的 Base64 编码字符串在 GDI+ 中创建图像?
Posted
技术标签:
【中文标题】如何从 C++ 中的 Base64 编码字符串在 GDI+ 中创建图像?【英文标题】:How can I create an Image in GDI+ from a Base64-Encoded string in C++? 【发布时间】:2010-04-30 18:42:52 【问题描述】:我有一个应用程序,目前是用 C# 编写的,它可以采用 Base64 编码的字符串并将其转换为图像(在本例中为 TIFF 图像),反之亦然。在 C# 中,这实际上非常简单。
private byte[] ImageToByteArray(Image img)
MemoryStream ms = new MemoryStream();
img.Save(ms, System.Drawing.Imaging.ImageFormat.Tiff);
return ms.ToArray();
private Image byteArrayToImage(byte[] byteArrayIn)
MemoryStream ms = new MemoryStream(byteArrayIn);
BinaryWriter bw = new BinaryWriter(ms);
bw.Write(byteArrayIn);
Image returnImage = Image.FromStream(ms, true, false);
return returnImage;
// Convert Image into string
byte[] imagebytes = ImageToByteArray(anImage);
string Base64EncodedStringImage = Convert.ToBase64String(imagebytes);
// Convert string into Image
byte[] imagebytes = Convert.FromBase64String(Base64EncodedStringImage);
Image anImage = byteArrayToImage(imagebytes);
(而且,现在我正在研究它,可以进一步简化)
我现在有业务需要在 C++ 中执行此操作。我正在使用 GDI+ 来绘制图形(目前仅适用于 Windows),并且我已经拥有 decode C++ 中的字符串(到另一个字符串)的代码。然而,我遇到的问题是将信息放入 GDI+ 中的 Image 对象中。
在这一点上,我认为我需要任何一个
a) 一种将 Base64 解码字符串转换为 IStream 以提供给 Image 对象的 FromStream 函数的方法
b) 一种将 Base64 编码的字符串转换为 IStream 以提供给 Image 对象的 FromStream 函数的方法(因此,与我当前使用的代码不同)
c) 一些完全不同的方式我在这里没有想到。
我的 C++ 技能非常生疏了,而且我也被托管的 .NET 平台宠坏了,所以如果我攻击这一切都是错误的,我愿意接受建议。
更新:除了我在下面发布的解决方案之外,我还想出了如何go the other way 如果有人需要它。
【问题讨论】:
为什么不在 Reflector 中打开它,看看 .NET 是如何做到的? 如果不详细查看它们,来自 Boost.Serialization 的数据流迭代器可能对 (base64 -> binary) 有帮助 ...boost.org/doc/libs/1_42_0/libs/serialization/doc/dataflow.html 好吧,继续使用 Google 搜索您的问题的答案并看到 #1 或 #2 结果是您刚刚提出的问题,这有点奇怪。 【参考方案1】:好的,使用我链接的 Base64 解码器和 Ben Straub 链接的示例中的信息,我得到了它的工作
using namespace Gdiplus; // Using GDI+
Graphics graphics(hdc); // Get this however you get this
std::string encodedImage = "<Your Base64 Encoded String goes here>";
std::string decodedImage = base64_decode(encodedImage); // using the base64
// library I linked
DWORD imageSize = decodedImage.length();
HGLOBAL hMem = ::GlobalAlloc(GMEM_MOVEABLE, imageSize);
LPVOID pImage = ::GlobalLock(hMem);
memcpy(pImage, decodedImage.c_str(), imageSize);
IStream* pStream = NULL;
::CreateStreamOnHGlobal(hMem, FALSE, &pStream);
Image image(pStream);
graphics.DrawImage(&image, destRect);
pStream->Release();
GlobalUnlock(hMem);
GlobalFree(hMem);
我确信它可以大大改进,但它确实有效。
【讨论】:
【参考方案2】:这应该是一个两步的过程。首先,将 base64 解码为纯二进制(如果您从文件中加载 TIFF,您将拥有的位)。这个first Google result 看起来不错。
其次,您需要将这些位转换为位图对象。当我不得不从资源表中加载图像时,我关注了this example。
【讨论】:
好的,这基本上就是答案。当我在谷歌搜索时,我一直在这些页面上运行,但由于我正在处理字符串或字节数组,我不知道如何合并这两个概念(第二篇文章正在从表中寻找资源)。我刚刚想通了,我会在星期一发布代码/答案。 在下面查看我的答案 - 我就是这样做的,但我想我会给别人代表回答它:)以上是关于如何从 C++ 中的 Base64 编码字符串在 GDI+ 中创建图像?的主要内容,如果未能解决你的问题,请参考以下文章
如何从 base64 编码的字符串构造 java.security.PublicKey 对象?
如何使用 PHP 从 base64 编码的数据/字符串创建图像并将其保存到网站文件夹
如何在 JavaScript 中使用字节数组将字符串转换为 base64 编码?