I have a Word add-in that has a WPF window that is launched from a Ribbon button. The WPF window is used for capturing pictures from webcam. It has two windows: Live and Snap. It also has three buttons: Start (shows live video in Live), Capture (copies the current frame of Live into Snap) and Close (closes the form). It also has a dropdown for selecting the correct camera.
I have a working code as Windows Forms here:
private void StartButton_Click(object sender, EventArgs e)
{
FinalFrame = new VideoCaptureDevice(CaptureDevice[cboDevices.SelectedIndex].MonikerString);
FinalFrame.NewFrame += FinalFrame_NewFrame;
FinalFrame.Start();
}
private void FinalFrame_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
pboLive.Image = (Bitmap)eventArgs.Frame.Clone();
}
But with WPF I had a problem with threads. Now with help of people here: WPF Calling thread cannot access with eventargs I got it to work with WPF, but it works exactly once - if I try to press start after closing the form one the Live stays empty.
private FilterInfoCollection CaptureDevice;
private VideoCaptureDevice FinalFrame;
private void Grid_Loaded(object sender, RoutedEventArgs e)
{
capturedpictures.Clear();
CaptureDevice = new FilterInfoCollection(FilterCategory.VideoInputDevice);
cboDevices.Items.Clear();
foreach (FilterInfo Device in CaptureDevice)
{
cboDevices.Items.Add(Device.Name);
}
cboDevices.SelectedIndex = cboDevices.Items.Count - 1;
FinalFrame = new VideoCaptureDevice();
}
private void StartButton_Click(object sender, RoutedEventArgs e)
{
int capturedeviceindex = cboDevices.SelectedIndex;
FilterInfo cd = CaptureDevice[cboDevices.SelectedIndex];
string cdms = cd.MonikerString;
FinalFrame = new VideoCaptureDevice(cdms);
FinalFrame.NewFrame += FinalFrame_NewFrame;
FinalFrame.Start();
}
And this handles new frames:
private void FinalFrame_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
this.Dispatcher.Invoke(
new Action<Bitmap>(
(bitmap) =>
{
pboLive.Source = ImageSourceForBitmap(bitmap);
return;
}
),
(Bitmap)eventArgs.Frame.Clone()
);
}
public ImageSource ImageSourceForBitmap(Bitmap bmp)
{
var handle = bmp.GetHbitmap();
try
{
return Imaging.CreateBitmapSourceFromHBitmap(handle, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
}
finally { DeleteObject(handle); }
}
And this closes the form:
private void CaptureWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
}
When debugging the re-start, code gets stuck at FinalFrame_NewFrame and displays nothing at pboLive.