我在内存中有一个BGR 24位图像作为连续缓冲区(用表示cv::Mat
,如果有帮助的话)。我想将其加载ID2D1Bitmap1
到位图以进行2D渲染。我有以下工作代码(在此处显示伪代码):
IWICImagingFactory::CreateBitmapFromMemory(GUID_WICPixelFormat24bppBGR);
IWICFormatConverter::Initialize(GUID_WICPixelFormat32bppRGB);
ID2D1DeviceContext::CreateBitmapFromWicBitmap;
效果很好,主要的问题是时间:20-40毫秒,对于我的应用程序来说太长了。我正在寻找优化过程的方法。
ID2D1Bitmap1
通过执行一次,然后使用可以从内存中加载转换后的图像,我大概可以节省的创建时间CopyFromMemory
,但是转换本身仍需要大量时间。一种方法是将原始BGR缓冲区加载到GPU内存,然后在GPU本身上将其转换为本机RGBA格式,但是我不知道如何开始。
您的第二个想法正是您应该走的方向。ID2D1Bitmap
一次创建一个(多个),转换缓冲区(在下面进行更多介绍),然后使用CopyFromMemory
。我在一个应用程序中做了非常相似的事情,该应用程序提供了已连接网络摄像头(可能具有多种格式之一)的预览。某些相机会以MJPEG,YUY2等格式传送图像。
该应用使用MediaFoundation
和IMFTransform
来转换缓冲区。在IMFTransform
这种情况下是的一个实例CLSID_CColorConvertDMO
(其使用SIMD寄存器/指令如果可能)。然而,之前完成的是,我与自己的转换代码(这是CPU的约束,并进行马马虎虎),并与另一溶液测试HLSL
和DirectCompute
(表现良好,但只能处理一种格式)。最后,我选择CLSID_CColorConvertDMO
处理各种类型的输入,但是如果您只有一种已知类型,则可以选择使用HLSL
解决方案(尽管这将导致您必须编写转换代码,并设置输入的“视图”数据)。
但是,如果您选择MediaFoundation
路线,则可以不使用IMFTransform
图表的所有其余部分(源,汇等)。创建CLSID_CColorConvertDMO
实例并设置输入和输出类型(格式,帧大小等)之后,创建IMFSample(使用MFCreateSample)和IMFMediaBuffer(使用MFCreateMemoryBuffer)到示例(使用IMFSample :: AddBuffer),然后进行所有操作必要的是调用ProcessInput和ProcessOutput转换缓冲区(先创建所有项目)。这听起来可能很多,但是如果操作正确,CPU使用率将不会受到明显影响,即使对于通常以60 FPS以上的速度提供大型帧的采集卡(使用了DataPath的采集卡),您也将获得所需的性能。和过去的Blackmagic采集卡)。
祝你好运。我敢肯定你会喜欢的。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句