[英]How to render video from raw frames in WPF?
I have a special video camera (using GigEVision protocol) that I control using a provided library. 我有一台特殊的摄像机(使用GigEVision协议),可以使用提供的库进行控制。 I can subscribe to a frame received event and then access the frame data via a IntPtr.
我可以订阅接收到帧的事件,然后通过IntPtr访问帧数据。
In my old WinForms app I could render the frame by either creating a Bitmap object from the data and setting it to a PictureBox Image, or by passing the PictureBox handle to a function in the provided library which would draw directly on the area. 在我的旧WinForms应用程序中,我可以通过从数据创建Bitmap对象并将其设置为PictureBox Image或通过将PictureBox手柄传递给提供的库中直接在该区域上绘制的函数来渲染框架。
What is the best and fastest way to do a similar thing in WPF? 在WPF中执行相似操作的最佳和最快方法是什么? The video camera runs anywhere from 30 to 100 fps.
摄像机的运行速度为30到100 fps。
edit(1): 编辑(1):
Since the frame received event is not on the UI thread it has to work across threads. 由于框架接收事件不在UI线程上,因此它必须跨线程工作。
edit(2): 编辑(2):
I found a solution using WriteableBitmap: 我找到了使用WriteableBitmap的解决方案:
void camera_FrameReceived(IntPtr info, IntPtr frame)
{
if (VideoImageControlToUpdate == null)
{
throw new NullReferenceException("VideoImageControlToUpdate must be set before frames can be processed");
}
int width, height, size;
unsafe
{
BITMAPINFOHEADER* b = (BITMAPINFOHEADER*)info;
width = b->biWidth;
height = b->biHeight;
size = (int)b->biSizeImage;
}
if (height < 0) height = -height;
//Warp space-time
VideoImageControlToUpdate.Dispatcher.Invoke((Action)delegate {
try
{
if (VideoImageControlToUpdateSource == null)
{
VideoImageControlToUpdateSource =
new WriteableBitmap(width, height, 96, 96, PixelFormats.Gray8, BitmapPalettes.Gray256);
}
else if (VideoImageControlToUpdateSource.PixelHeight != height ||
VideoImageControlToUpdateSource.PixelWidth != width)
{
VideoImageControlToUpdateSource =
new WriteableBitmap(width, height, 96, 96, PixelFormats.Gray8, BitmapPalettes.Gray256);
}
VideoImageControlToUpdateSource.Lock();
VideoImageControlToUpdateSource.WritePixels(
new Int32Rect(0, 0, width, height),
frame,
size,
width);
VideoImageControlToUpdateSource.AddDirtyRect(new System.Windows.Int32Rect(0, 0, width, height));
VideoImageControlToUpdateSource.Unlock();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
});
}
In the above, VideoImageControlToUpdate
is a WPF Image control. 在上面,
VideoImageControlToUpdate
是WPF图像控件。
For more speed I believe the VideoRendererElement found on codeplex is faster. 为了获得更高的速度,我相信在Codeplex上找到的VideoRendererElement会更快。
Best way: WriteableBitmap.WritePixels(..., IntPtr source, ...) 最好的方法:WriteableBitmap.WritePixels(...,IntPtr源,...)
Fastest way: Use WIC and all operations in IntPtr unmanaged memory. 最快的方法:在IntPtr非托管内存中使用WIC和所有操作。 But why use WPF at all in this case?
但是,为什么在这种情况下完全使用WPF? Consider using DirectX overlay if that kind of performance is required.
如果需要这种性能,请考虑使用DirectX覆盖。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.