捕捉静止图像与微软表达式编码器SDK
本文关键字:表达式 编码器 SDK 微软 静止图像 | 更新日期: 2023-09-27 18:10:51
我正在玩我的网络摄像头,并开始创建一个小应用程序(使用Microsoft Expression Encoder SDK),其中网络摄像头的图像流式传输到winform上的图片框[1]。到目前为止,一切都很顺利。但现在我的问题开始了:
我想捕获视频流的单个图像并存储它。我找到了"screenapturejob"类,它能够创建视频文件。微软的MSDN指出,它可以"从对话框的静止图像捕捉任何东西"[2]来完成视频。MSDN中的所有示例都涉及视频捕获。不幸的是,我找不到任何解决方案如何使用这个类来捕获单个图像。
有人能帮我吗?
[1]将网络摄像头流到图片框的代码(来源:http://www.codeproject.com/Articles/202464/How-to-use-a-WebCam-in-C-with-the-NET-Framework-4)
var lstVideoDevices = new Dictionary<string, EncoderDevice>();
var lstAudioDevices = new Dictionary<string, EncoderDevice>();
foreach (EncoderDevice edv in EncoderDevices.FindDevices(EncoderDeviceType.Video))
{
lstVideoDevices.Add(edv.Name, edv);
}
foreach (EncoderDevice eda in EncoderDevices.FindDevices(EncoderDeviceType.Audio))
{
lstAudioDevices.Add(eda.Name, eda);
}
_job = new
var _deviceSource = _job.AddDeviceSource(lstVideoDevices.Values.FirstOrDefault(x => x.Name.Contains("USB")), lstAudioDevices.Values.FirstOrDefault(x => x.Name.Contains("USB")));
_deviceSource.PreviewWindow = new PreviewWindow(new HandleRef(this.pictureBox1, this.pictureBox1.Handle));
_job.ActivateSource(_deviceSource);`
[2] http://msdn.microsoft.com/en-us/library/gg602440%28v=expression.40%29.aspx
您可以使用该库进行静态捕获,但它似乎有点拼凑。(我还在寻找一个更好的解决方案)我在链接中找到了一个例子,基本的解决方案是弹出一个预览窗口,然后使用相同尺寸的图形对象,使用CopyFromScreen()来获取文件。
你可以,但它似乎有点拼凑。我在Code project上找到了一个例子——如何在c#中使用网络摄像头,基本的解决方案是弹出一个预览窗口。然后,使用相同尺寸的图形对象,使用CopyFromScreen()来获取文件。下面是代码:
using (Bitmap bitmap = new Bitmap(panelVideoPreview.Width, panelVideoPreview.Height))
{
using (Graphics g = Graphics.FromImage(bitmap))
{
// Get the paramters to call g.CopyFromScreen and get the image
Rectangle rectanglePanelVideoPreview = panelVideoPreview.Bounds;
Point sourcePoints = panelVideoPreview.PointToScreen(new Point(panelVideoPreview.ClientRectangle.X, panelVideoPreview.ClientRectangle.Y));
g.CopyFromScreen(sourcePoints, Point.Empty, rectanglePanelVideoPreview.Size);
}
bitmap.Save(....)
}
我不确定这是否可能与微软表达式编码器SDK,它似乎是很差的文档。
但是您可以使用Video Capture函数代替。
使用capCreateCaptureWindow
函数创建一个预览窗口,然后通过发送WM_CAP_SET_CALLBACK_FRAME
消息注册帧回调:
/* imports */
[DllImport("user32", EntryPoint="SendMessage")]
public static extern int SendMessage(int hWnd, uint Msg, int wParam, int lParam);
[DllImport("avicap32.dll", EntryPoint="capCreateCaptureWindowA")]
public static extern int capCreateCaptureWindowA(string lpszWindowName, int dwStyle, int X, int Y, int nWidth, int nHeight, int hwndParent, int nID);
/* ... */
capCreateCaptureWindowA(lpszName, showVideo.WS_VISIBLE | showVideo.WS_CHILD, 0, 0, mWidth, mHeight, mControlPtr, 0);
SendMessage(lwnd, showVideo.WM_CAP_SET_CALLBACK_FRAME, 0, handler);
你可以在这里和这里找到c#示例。
如果你知道如何用表达式编码器做到这一点,请让我知道。