我有一个Word加载项,它有一个从功能区按钮启动的WPF窗口。 WPF窗口用于从网络摄像头捕获图片。它有两个窗口:Live和Snap。它还有三个按钮:Start(在Live中显示实时视频),Capture(将Live的当前帧复制到Snap中)和Close(关闭表单)。它还有一个用于选择正确相机的下拉列表。
我在这里有一个工作代码作为Windows窗体:
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();
}
但是使用WPF我遇到了线程问题。现在在这里的人的帮助下:WPF Calling thread cannot access with eventargs 我得到它与WPF一起使用,但它只运行一次 - 如果我在关闭表单后尝试按下启动,则Live保持为空。
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();
}
这会处理新的框架:
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); }
}
这样就关闭了表格:
private void CaptureWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
}
调试重新启动时,代码卡在FinalFrame_NewFrame中,并且在pboLive上没有显示任何内容。
答案 0 :(得分:0)
这可能无法解答您的问题,但使用Excel时会出现一些警告(对于Word或其他任何使用COM的内容也是如此)
您在Word中使用的任何COM对象都需要小心处理。 COM确实引用计数,因此每次使用一个对象时,背景中的计数器基本上都是+1。 (是的,我知道它不仅仅是这个,但它是一个很好的设想方式)当你完成一个对象时,你需要告诉它-1,否则该对象永远不会被清除。要做到这一点:
Marshal.ReleaseComObject(o);
您必须确保为您使用的每个COM对象调用它,否则它将不会被释放并留在内存中。如果处理不当,可能会导致许多问题。
我会确保您使用上述内容减少参考,并查看问题是否仍然存在。我已经看到很多这样的问题,其中问题是以前的实例仍在内存中导致新实例正常工作的问题。
答案 1 :(得分:-1)
您是否可以像以前一样创建Bitmap
,然后调用ImageSourceForBitmap
方法?:
private void FinalFrame_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
this.Dispatcher.BeginInvoke(new Action(() =>
{
Bitmap bitmap = (Bitmap)eventArgs.Frame.Clone()
pboLive.Source = ImageSourceForBitmap(bitmap);
}));
}