如何在WPF中从原始帧渲染视频?

时间:2009-08-05 11:03:44

标签: c# wpf video

我有一个特殊的摄像机(使用GigEVision协议),我使用提供的库进行控制。我可以订阅一个帧接收事件,然后通过IntPtr访问帧数据。

在我的旧WinForms应用程序中,我可以通过从数据创建Bitmap对象并将其设置为PictureBox图像,或者将PictureBox句柄传递给提供的库中的函数来直接绘制区域来渲染帧。

在WPF中执行类似操作的最佳和最快方法是什么?摄像机的运行速度为30到100 fps。

编辑(1):

由于帧接收事件不在UI线程上,因此它必须跨线程工作。

修改(2):

我找到了一个使用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());
        }
    });
}

在上面,VideoImageControlToUpdate是一个WPF图像控件。

为了提高速度,我相信在codeplex上找到的VideoRendererElement更快。

1 个答案:

答案 0 :(得分:0)

最佳方式: WriteableBitmap.WritePixels(...,IntPtr source,...)

最快的方式: 在IntPtr非托管内存中使用WIC和所有操作。但是在这种情况下为什么要使用WPF呢?如果需要这种性能,请考虑使用DirectX覆盖。