我最近问了一个问题 How can I create an Image in GDI+ from a Base64-Encoded string in C++? ,得到了一个回复,让我得到答案。
现在我需要做相反的事情 - 我在GDI +中有一个Image,我的图像数据需要变成Base64-Encoded字符串。由于它的性质,它并不简单。
问题的关键在于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-Encode)?或者有更好的方法从GDI +图像转换为字符串?
答案 0 :(得分:0)
搞定了
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;
}
这个技巧受到我从this article得到的启发,就是知道找出流大小的方法,并将其读入字符数组。然后我可以将该数组提供给base64_encode
函数和voilà。