2009-07-07 35 views
4

これは私の最初の投稿です。私は問題があります。 私は、デスクトップのsceenshotを取る必要がありますjpegに変換し、バッファに格納し、それを操作し、インターネット上で送信します。メモリからjpegのサイズを取得する(GDI ++で変換)

これを行うためのコードは、HBITMAPをjpegに変換するためのGetDC ....とGDI +で書かれています。私が今問題を抱えているのは、IStreamに保存されているJPEGのサイズがわからないということです。以下は、HBITMAP hBackBitmapで参照されるビットマップをjpegに変換してpStreamに保存するコードの一部です。私は必要なもの

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

は次のとおりです:私は(PVOIDハンドルを取得)pStreamに書き込まれ、どのように私はpStreamを使用することができますされているどのように多くのバイトを知っておく必要があり 1 JPEGのサイズを調べ、どのように多くのバイトストリームに書かれている。 2.ストリームの使い方。たとえば、ストリーム内のデータのPVOIDを取得できますか?

ありがとうございます。

答えて

5

the CreateStreamOnHGlobalによると、あなたの使い方はすばらしいものです。引用:

メモリブロックの現在の内容は、新しいストリームオブジェクトの作成によって損なわれません。したがって、この関数を使用してメモリ内の既存のストリームを開くことができます。 ストリームの初期サイズは、GlobalSize関数によって返されるメモリハンドルのサイズです。

したがって、ゼロサイズのバッファを割り当てるには、nBlockSizeを0に置き換える必要があります。メモリバッファが可動でなければならないとして、あなたはまた、GMEM_MOVEABLEでGMEM_FIXEDを交換する必要があります:

HGLOBAL gGlobal = GlobalAlloc(GMEM_MOVEABLE, 0); 

ストリームに保存した後、得られたサイズはJPEGにアクセスするには

size_t size = GlobalSize(hGlobal); 

として利用できるようになりますメモリ内の実際の場所へのポインタを取得するには、GlobalLockを使用する必要があります。

グローバル関数とローカル関数は廃止予定とマークされており、もう使用しないようにしてください。ただし、MSDNドキュメントをクロールせずにニーズに合わせてIStreamを実装する方法はわかりません。多分誰かがここで助けることができます!

+0

ありがとうございます。 ストリームに余分なメモリを割り当てる必要がないので、これは良い解決策です。 – Nemok

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; 
関連する問題