5

これが私の最初の投稿です。私は問題があります。デスクトップのシーンショットを撮り、それをjpegに変換し、バッファーに保存してから、操作してインターネット経由で送信する必要があります。

GetDC....とHBITMAPをjpegに変換するためのGDI+でこれを行うためのコードを作成しました。私が今抱えている問題は、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を取得できますか?

ありがとうございました。

4

2 に答える 2

5

CreateStreamOnHGlobalのドキュメントによると、それを使用することは不適切です。引用:

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

したがって、ゼロサイズのバッファを割り当てるには、nBlockSizeを0に置き換える必要があります。メモリバッファは移動可能である必要があるため、GMEM_FIXEDをGMEM_MOVEABLEに置き換える必要もあります。

HGLOBAL gGlobal = GlobalAlloc(GMEM_MOVEABLE, 0);

ストリームに保存した後、結果のサイズは次のように利用できるようになります

size_t size = GlobalSize(hGlobal);

JPEGでエンコードされたデータにアクセスするには、GlobalLockを使用して、メモリ内の実際の場所へのポインタを取得する必要があります。

グローバル関数とローカル関数は非推奨としてマークされており、今後は使用しないでください。ただし、MSDNドキュメントをクロールせずに、ニーズに合ったIStreamの実装を改善することはできません。おそらく他の誰かがここで助けることができます!?

于 2009-07-07T09:08:35.677 に答える
2

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;
于 2009-07-07T09:12:13.190 に答える