CImage::Load() 从内存而不使用 CreateStreamOnHGlobal

Posted

技术标签:

【中文标题】CImage::Load() 从内存而不使用 CreateStreamOnHGlobal【英文标题】:CImage::Load() from memory without using CreateStreamOnHGlobal 【发布时间】:2016-12-06 02:17:09 【问题描述】:

我正在显示来自摄像机的实时取景视频。我将每一帧下载到一个字节数组(pImageData)中,我必须分配它。

现在,为了显示,我正在使用 CImage (MFC)。 但是,我找到的所有示例都基于使用 GlobalAlloc,还有另一个 memcpy 和 CreateStreamOnHGlobal。

我想避免进行另一次分配/解除分配和内存复制。每帧超过 2mb,我正在推动 30 fps!

是否可以在基于非 HGLOBAL 的内存上创建 IStream? 要么 是否可以强制 Image::Load() 使用字节数组?

代码如下:

// pImageData is an array with bytes, size is the sizeOfThatArray

CComPtr<IStream> stream;

HGLOBAL hMem = ::GlobalAlloc(GHND, size);
LPVOID pBuff = ::GlobalLock(hMem);

memcpy(pBuff, pImageData, size); // <-- would like to avoid this

::GlobalUnlock(hMem);

CreateStreamOnHGlobal(hMem, TRUE, &stream); // <-- or create stream on non-hglobal memory

CImage image;
image.Load(stream); // <-- Or load directly from pImageData

// .. display image

image.Destroy();

::GlobalFree(hMem);

【问题讨论】:

你的字节数组中的图片数据是什么格式的?是位图吗?它有任何标题吗? 你可以在任何你喜欢的东西上创建一个IStream。它只是一个定义的接口,您实际上可以实现任何您想要的方法。 @o_wiseman - 我不能 100% 确定,它的原始数据来自 DSLR 取景器。我的猜测是它是一个普通的位图,考虑到在所有 GlobalLock/memcpy 操作链中没有对数据本身做任何事情。 msdn.microsoft.com/en-us/library/windows/desktop/… 如果它没有复制数据,文档必须明确原始内存需要保持有效,直到 IStream 上的最后一个引用被释放。他们没有说任何类似的东西,所以很明显,副本是在内部进行的。 【参考方案1】:

感谢 Hans 指出我不知道存在的 SHCreateMemStream。 代码干净多了,但还是不确定SHCreateMemStream内部是否创建了副本(文档不清楚)

[edit] 根据 Jonathan 的 cmets,看起来它仍然需要在内部进行复制。当..

最终代码

// pImageData is an array with bytes, size is the sizeOfThatArray

// Still not clear if this is making a copy internally
IStream* pMemStream = SHCreateMemStream(pImageData, size);

CComPtr<IStream> stream;

stream.Attach(pMemStream); // Need to Attach, otherwise ownership is not transferred and we leak memory

CImage image;
image.Load(stream); 

// .. display image

image.Destroy();

// No need for further cleanup, CComPtr does the job

【讨论】:

只是链接我发现的这个,因为它与“需要附加”评论相关 The difference between assignment and attachment with ATL smart pointers 当然如果你也想要,你可以手动 stream-&gt;Release(); 而不使用 CComPtr

以上是关于CImage::Load() 从内存而不使用 CreateStreamOnHGlobal的主要内容,如果未能解决你的问题,请参考以下文章

驱动开发:内核CR3切换读写内存

从python内存中的MPEG(.ts)文件中提取音频,而不将MPEG写入文件

<canvas>:从内存中删除 2d 上下文而不从内存中删除 webgl 上下文

如何从 PHP 扩展返回数组,而不将其复制到内存中?

从文本文件中读取第一行而不将整个文本文件加载到内存中

裁剪图像而不加载到内存中