2010-05-13 84 views
1

我最近问了一个问题,How can I create an Image in GDI+ from a Base64-Encoded string in C++?,得到了回应,导致我的答案。如何从C++中的GDI +图像创建Base64编码的字符串?

现在我需要做相反的事情 - 我有一个图像在GDI +的图像数据,我需要变成一个Base64编码字符串。由于其性质,这不是直接的。

问题的症结在于,GDI +中的Image可以将其数据保存到文件或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 code

现在我要去产生的图像上进行操作,在这种情况下旋转想通了,现在我完成后需要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. 

GetEncoderClsid

所以我风与末是一个IStream *对象。但是这里是我的知识和Google为我分解的地方。 IStream本身不应该是一个对象,它是其他类型流的接口。我反过来从字符串 - >图像的道路上走下去,但我不知道如何确定流的大小,这似乎是该路线的关键。

如何从一个IStream *转换为一个字符串(然后我将Base64-Encode)?或者是否有更好的方式从GDI +图像转换为字符串?

回答

1

得到它

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à。

相关问题