C++ 从内存中获取jpeg的大小(使用GDI+;+;)转换)

C++ 从内存中获取jpeg的大小(使用GDI+;+;)转换),c++,gdi+,bitmap,jpeg,screenshot,C++,Gdi+,Bitmap,Jpeg,Screenshot,这是我在这里的第一篇文章。我有个问题。 我需要对桌面进行扫描,将其转换为jpeg格式,将其存储在缓冲区中,然后对其进行操作并通过互联网发送 我已经编写了使用GetDC…和GDI+将HBITMAP转换为jpeg的代码。我现在遇到的问题是,我不知道保存到IStream中的jpeg的大小。下面是将HBITMAP hBackBitmap引用的位图转换为jpeg并保存为pStream的部分代码。我需要知道有多少字节已写入pStream,以及如何使用pStream(获取PVOID句柄): 我需要的是: 1.

这是我在这里的第一篇文章。我有个问题。 我需要对桌面进行扫描,将其转换为jpeg格式,将其存储在缓冲区中,然后对其进行操作并通过互联网发送

我已经编写了使用GetDC…和GDI+将HBITMAP转换为jpeg的代码。我现在遇到的问题是,我不知道保存到IStream中的jpeg的大小。下面是将HBITMAP hBackBitmap引用的位图转换为jpeg并保存为pStream的部分代码。我需要知道有多少字节已写入pStream,以及如何使用pStream(获取PVOID句柄):

我需要的是: 1.找出jpeg的大小,流中写入了多少字节 2.如何使用流。例如,我可以为流中的数据获取PVOID吗

谢谢。

根据文档,您对它的使用是不正确的。引述:

内存块的当前内容不会因创建新的流对象而受到干扰。因此,您可以使用此函数打开内存中的现有流。 流的初始大小是GlobalSize函数返回的内存句柄的大小

因此,应该用0替换nBlockSize以分配一个大小为零的缓冲区。由于内存缓冲区必须是可移动的,您还需要将GMEM_FIXED替换为GMEM_moveable:

HGLOBAL gGlobal = GlobalAlloc(GMEM_MOVEABLE, 0);
保存到流后,生成的大小将如下所示:

size_t size = GlobalSize(hGlobal);
要访问JPEG编码的数据,需要使用GlobalLock获取指向内存中实际位置的指针


请注意,全局和本地函数被标记为已弃用,不应再使用,但如果不抓取MSDN文档,我不知道有什么更好的IStream实现可以满足您的需要。也许其他人能帮上忙

好的,我在这里找到了这个问题的解决方案:

我也会把它放在这里以备将来参考。 要找出已写入流的大小,可以使用流的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;

非常感谢。这是一个很好的解决方案,因为我不需要为流分配额外的内存。
   // 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;