2010-05-13 44 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à。

相關問題