I have a special video camera (using the GigEVision protocol), which I control using the provided library. I can subscribe to the received frame event, and then access the frame data through IntPtr.
In my old WinForms application, I could visualize the frame by creating a Bitmap object from the data and setting it to the PictureBox, or by passing the PictureBox handle to a function in the library that will draw directly in the area.
What is the best and fastest way to do this in WPF? The camcorder runs from 30 to 100 frames per second.
edit (1):
Since the event received by the frame is not in the user interface thread, it must work through the threads.
edit (2):
I found a solution using 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;
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());
}
});
}
The above example VideoImageControlToUpdateis a WPF image control.
For more speed, I find the VideoRendererElement found on codeplex is faster.