代码之家  ›  专栏  ›  技术社区  ›  Tom Kidd

如何从C++中的Base64编码字符串创建GDI+中的图像?

  •  4
  • Tom Kidd  · 技术社区  · 14 年前

        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);
    

    (而且,现在我在看,可以进一步简化)

    decode C++中的字符串(另一个字符串)。然而,我遇到的问题是如何将信息导入GDI+中的图像对象中。

    现在我想我需要

    a) 一种将Base64解码字符串转换为IStream以提供给Image对象的FromStream函数的方法

    我的C++技巧是 rusty和我也被托管的.NET平台宠坏了,所以如果我攻击这一切都是错误的,我愿意接受建议。

    更新: 除了我在下面发布的解决方案之外,我还发现了如何 go the other way 如果有人需要的话。

    2 回复  |  直到 7 年前
        1
  •  4
  •   Ben Straub    14 年前

    这应该是一个两步的过程。首先,将base64解码为纯二进制(如果从文件中加载TIFF,则会得到的位)。这个 first Google result

    其次,需要将这些位转换为位图对象。我跟着 this example

        2
  •  8
  •   Tom Kidd    14 年前

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