【发布时间】:2023-05-08 19:43:01
【问题描述】:
我有一个特殊的摄像机(使用 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 Image 控件。
为了更快的速度,我相信在 codeplex 上找到的 VideoRendererElement 更快。
【问题讨论】: