如何创建从GDI +图片C ++中的Base64编码恩codeD字符串? [英] How can I create a Base64-Encoded string from a GDI+ Image in C++?

查看:121
本文介绍了如何创建从GDI +图片C ++中的Base64编码恩codeD字符串?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我问一个问题最近的 How我可以在GDI +的在C Base64编码恩codeD字符串++创建一个图片? 的,它得到了,导致我的回答的响应。

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.

现在我需要做相反的 - 我GDI +的图像数据,我需要变成一个Base64恩codeD字符串有一个形象。由于其性质,它不是简单的。

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.

问题的关键是,在GDI图像+可以在其数据保存到任何文件或一个IStream *。我不想保存到一个文件,所以我需要使用所产生的数据流。问题是,这是我的知识分解。

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

的Base64 code

现在我要去产生的图像上旋转它进行操作,在这种情况下,现在我想,当我完成的Base64等效的字符串。

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. 

GetEn coderClsid

所以,我风与结尾是一个IStream *的对象。但是,这里的地方我都知道和谷歌打破了我。的IStream不应该是一个对象本身,这对其它类型的流的接口。我想从得到与字符串>图像沿着这条路走反向,但我不知道如何确定流,这似乎是关键,这条路线的大小。

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.

我如何从一个IStream *去一个字符串(我会那么的Base64恩$ C $三)?还是有更好的方式,从一个GDI +图片为一个字符串去?

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?

推荐答案

明白了

std::string RotateImage(const std::string &Base64EncodedImage)
{
    // Initialize GDI+.
    GdiplusStartupInput gdiplusStartupInput;
    ULONG_PTR gdiplusToken;
    GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

    std::string decodedImage = base64_decode(Base64EncodedImage);

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

    image.RotateFlip(Gdiplus::Rotate180FlipNone);

    pStream->Release();
    GlobalUnlock(hMem);
    GlobalFree(hMem);

    IStream* oStream = NULL;
    CreateStreamOnHGlobal(NULL, TRUE, (LPSTREAM*)&oStream);

    CLSID tiffClsid;
    GetEncoderClsid(L"image/tiff", &tiffClsid);
    image.Save(oStream, &tiffClsid);

    ULARGE_INTEGER ulnSize;
    LARGE_INTEGER lnOffset;
    lnOffset.QuadPart = 0;
    oStream->Seek(lnOffset, STREAM_SEEK_END, &ulnSize);
    oStream->Seek(lnOffset, STREAM_SEEK_SET, NULL);

    char *pBuff = new char[(unsigned int)ulnSize.QuadPart];
    ULONG ulBytesRead;
    oStream->Read(pBuff, (ULONG)ulnSize.QuadPart, &ulBytesRead);

    std::string rotated_string = base64_encode((const unsigned char*)pBuff, ulnSize.QuadPart);

    return rotated_string;
}

这一招,因为灵感是我从这篇文章了< /一>,是知道的方法来找出流的大小,并具有其读入的字符阵列。然后,我可以养活该数组的 base64_en code 函数就万事大吉。

这篇关于如何创建从GDI +图片C ++中的Base64编码恩codeD字符串?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆