2009-07-07 58 views
4

這是我第一篇文章。我有個問題。 我需要拍攝一個桌面的sceenshot,將其轉換爲jpeg,將其存儲在緩衝區中,然後對其進行處理並通過互聯網發送。從內存中獲取jpeg的大小(使用GDI ++轉換)

我已經用GetDC ....和GDI +編寫了用於將HBITMAP轉換爲jpeg的代碼。我現在遇到的問題是我不知道已經保存到IStream中的jpeg的大小。以下是將HBITMAP hBackBitmap引用的位圖轉換爲jpeg並將其保存到pStream中的代碼的一部分。我需要知道有多少字節被寫入pStream,我怎麼能使用pStream(獲得PVOID手柄):

Gdiplus::Bitmap bitmap(hBackBitmap, NULL);///loading the HBITMAP 
CLSID clsid; 
GetEncoderClsid(L"image/jpeg", &clsid); 
HGLOBAL hGlobal = GlobalAlloc(GMEM_FIXED, nBlockSize) ;//allocating memory, the size of the current bitmap size. i'm over allocating but i don't think there is any way to get the exact ammount I need to allocate, is there? 
if(!hGlobal) 
    return; 
IStream* pStream = NULL ; 
if(CreateStreamOnHGlobal(hGlobal, TRUE, &pStream) != S_OK) 
    return; 
bitmap.Save(pStream, &clsid); 

我需要的是:1。 找出JPEG的大小,多少字節已經寫入流中 2.如何使用流。例如,我可以爲流中的數據獲取PVOID嗎?

謝謝。

回答

5

根據the CreateStreamOnHGlobal文檔,您的使用是不合法的。報價:

內存塊的當前內容不受創建新的流對象的干擾。因此,您可以使用此功能打開內存中的現有流。 流的初始大小是由GlobalSize函數返回的內存句柄的大小。

因此,您應該用0替換nBlockSize以分配零大小的緩衝區。由於內存緩衝區必須是可移動的,你還需要與GMEM_MOVEABLE更換GMEM_FIXED:

HGLOBAL gGlobal = GlobalAlloc(GMEM_MOVEABLE, 0); 

保存到流後,所產生的規模將可作爲

size_t size = GlobalSize(hGlobal); 

要訪問JPEG編碼數據,您需要使用GlobalLock來獲取指向內存中實際位置的指針。

注意整體和局部功能都被標記爲已過時,不應再使用,但我不知道你需要一個更好的IStream實現無爬行的MSDN文檔。也許別人可以在這裏幫助!?

+0

謝謝。 這是一個很好的解決方案,因爲我不需要爲流分配額外的內存。 – Nemok 2009-07-07 10:26:50

1

OK我找到了解決這個問題在這裏: http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/6dfc2e62-e2d1-4be3-a93b-a7d97d3f8469

我也會把它放在這裏供將來參考。 要找出已寫入流的大小,可以使用流的Seek方法。要訪問緩衝區,可以使用Read。

// Calculate reasonably safe buffer size 
    int stride = 4 * ((image.GetWidth() + 3)/4); 
    size_t safeSize = stride * image.GetHeight() * 4 + sizeof(BITMAPINFOHEADER) + sizeof(BITMAPFILEHEADER) + 256 * sizeof(RGBQUAD); 
    HGLOBAL mem = GlobalAlloc(GHND, safeSize); 
    assert(mem); 

    // Create stream and save bitmap 
    IStream* stream = 0; 
    hr = CreateStreamOnHGlobal(mem, TRUE, &stream); 
    assert(hr == S_OK); 
    hr = image.Save(stream, Gdiplus::ImageFormatBMP); 
    assert(hr == S_OK); 

    // Allocate buffer for saved image 
    LARGE_INTEGER seekPos = {0}; 
    ULARGE_INTEGER imageSize; 
    hr = stream->Seek(seekPos, STREAM_SEEK_CUR, &imageSize); 
    assert(hr == S_OK && imageSize.HighPart == 0); 
    BYTE* buffer = new BYTE[imageSize.LowPart]; 

    // Fill buffer from stream 
    hr = stream->Seek(seekPos, STREAM_SEEK_SET, 0); 
    assert(hr == S_OK); 
    hr = stream->Read(buffer, imageSize.LowPart, 0); 
    assert(hr == S_OK); 


    // Cleanup 
    stream->Release(); 
    delete[] buffer; 
    return 0; 
相關問題