如何在C ++中使用Base64-Encoded字符串在GDI +中创建图像?

时间:2010-04-30 18:42:52

标签: c++ image gdi+ base64 tiff

我有一个应用程序,目前用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

2 个答案:

答案 0 :(得分:8)

好的,使用我链接的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);

我确信它可以大大改进,但它确实有效。

答案 1 :(得分:4)

这应该是一个两步的过程。首先,将base64解码为纯二进制文件(如果从文件加载TIFF,您将拥有的位数)。这个first Google result看起来非常好。

其次,您需要将这些位转换为Bitmap对象。当我不得不从资源表加载图像时,我跟着this example