我想使用DirectShow在Windows上拍摄网络摄像头快照。这些快照将保存到磁盘,而不会显示这些图像。我想启动一个快照过程,该过程每秒钟拍摄一次快照,直到停止为止,而主过程继续进行。
因此,我选择DirectShow的Yet Another Web Camera Control与C#一起使用,演示可以正常工作。
但是当我在自己的任务中使用包装器时遇到问题,我遇到了典型的线程错误The calling thread cannot access this object because a different thread owns it.
调用代码如下:
Task.Run(() =>
{
using (var cam1 = new SnapshotCam(camList.First(), "person", webCameraControl))
{
// Act
Bitmap image = null;
if (!cam1._wcc.IsCapturing)
{
cam1._wcc.StartCapture(cam1._cameraId);
Task.Delay(500).Wait();
}
image = cam1._wcc.GetCurrentImage();
// Assert
Assert.NotNull(image);
}
}).Wait();
我很难处理的对象是存储在webCameraControl
中的cam1._wcc
:该对象继承自System.Windows.Controls.UserControl
,可以附加到UI。但就我而言,我没有任何用户界面,必须以“无头”样式拍摄快照。
因此,当我想使用_wcc
对象时,麻烦就开始了。我已经尝试为相应的线程调用_wcc.Dispatcher
,但是没有成功。
如何在独立于其余代码的任务/线程中调用以上代码?
答案 0 :(得分:1)
您立即遇到的问题与线程相关,但是最终这不是一个用于摄像头捕获的不幸选择。您不需要显示摄像机帧,但是库正在实现通过将视频流渲染到Direct3D设备(即使它是“不可见的”,即使是不可见的演示)来拍摄静止图像,并根据需要复制最后一个已知的帧。
也许您应该更喜欢DirectShow.NET软件包中的DxSnap
示例应用程序。即使也不理想:
另请参阅:
答案 1 :(得分:0)
如果您没有UI,则可能不需要将代码包装在Task.Run
中,除非您试图在运行时同时进行某些操作-并且因为您没有使用await它不是/ look /那样的。
如果要将其保留在Task.Run中,则可以在表单上使用Invoke
方法,该方法将允许您在正确的线程中访问相机控件,但是我看不到如何解决异步运行的问题。
如果您没有将控件用作实际的UI元素,那么我不会明白为什么不能在单独的线程上创建它并在该线程上使用它,尽管听起来并不像预期的那样使用。