无忧编程_ASP.NET  / C# / PHP 程序员的软件世界

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 2931|回复: 1

C# 调用AForge类库操作摄像头实现拍照录像功能

[复制链接]

245

主题

272

帖子

1095

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1095
发表于 2016-2-12 15:01:17 | 显示全部楼层 |阅读模式
C# 调用AForge类库操作摄像头实现拍照录像功能:

如有雷同,不胜荣幸,若转载,请注明

最近做项目需要操作摄像头,在网上百度了很多资料,很多都是C#调用window API 发送SendMessage,实现操作摄像头,但是C#调用window API的时候因为驱动的问题,总是弹出视频选择对话框,让人很是无语,看到大牛们有的截获到了window消息,然后模拟点击确定按钮,这是在是不敢恭维啊,还有的大牛根据API原型重写了,至于我是一只IT小小鸟了,然后在继续百度,找到了一个AForge强大的C#类库,最后终于搞定了,接下来将我拙劣的代码部分贴出来,以便同行或者需要的朋友学习交流,

首先用到AForge类库下载地址:http://www.aforgenet.com/

然后引用AForge,AForge.Controls(这个是控件,可以添加到工具箱中),AForge.Imaging,AForge.Video,AForge.Video.DirectShow;

然后直接上代码:

[C#] 纯文本查看 复制代码
private FilterInfoCollection videoDevices;
private VideoCaptureDevice videoSource;

public int selectedDeviceIndex = 0;



下面是获取设备:
[C#] 纯文本查看 复制代码
public FilterInfoCollection GetDevices()
        {
            try
            {
                //枚举所有视频输入设备
                videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
                if (videoDevices.Count != 0)
                {
                    LogClass.WriteFile("已找到视频设备.");
                    return videoDevices;
                }
                else
                    return null;
            }
            catch (Exception ex)
            {
                LogClass.WriteFile("error:没有找到视频设备!具体原因:" + ex.Message);
                return null;
            }

        }



选择设备,然后连接摄像头:
[C#] 纯文本查看 复制代码
/// <summary>
        /// 连接视频摄像头
        /// </summary>
        /// <param name="deviceIndex"></param>
        /// <param name="resolutionIndex"></param>
        /// <returns></returns>
        public VideoCaptureDevice VideoConnect(int deviceIndex = 0, int resolutionIndex = 0)
        {
            if (videoDevices.Count <= 0)
                return null;
            selectedDeviceIndex = deviceIndex;
            videoSource = new VideoCaptureDevice(videoDevices[deviceIndex].MonikerString);</p><p>            return videoSource;

        }
//抓图,拍照,单帧
public void GrabBitmap(string path)
        {
            if (videoSource == null)
                return;
            g_Path = path;
            videoSource.NewFrame += new NewFrameEventHandler(videoSource_NewFrame);
        }




void videoSource_NewFrame(object sender, AForge.Video.NewFrameEventArgs eventArgs)
        {
            Bitmap bmp = (Bitmap)eventArgs.Frame.Clone();
            string fullPath = path + "temp\\";
            if (!Directory.Exists(fullPath))
                Directory.CreateDirectory(fullPath);
            string img = fullPath + DateTime.Now.ToString("yyyyMMdd hhmmss") + ".bmp";
            bmp.Save(img);
//如果这里不写这个,一会儿会不停的拍照,
            videoSource.NewFrame -= new NewFrameEventHandler(videoSource_NewFrame);
        }

windows .net(C#+MSSQL) linux(php+mysql)  
回复

使用道具 举报

245

主题

272

帖子

1095

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1095
 楼主| 发表于 2016-2-12 15:03:29 | 显示全部楼层
C#调用本机摄像头
这段时间一个小项目中需要调用本机的摄像头进行拍照,网上搜集了一些资料以及解决的一些小问题,在此记录以便后续使用。
硬件环境:联想C360一体机,自带摄像头
编写环境:vs2010
语言:C# WPF

下载AForge类库,并添加引用:
[C#] 纯文本查看 复制代码
using AForge;
using AForge.Controls;
using AForge.Video;
using AForge.Video.DirectShow;
using Size = System.Drawing.Size;

在xaml界面中添加VideoSourcePlayer控件,此次稍微解释如何添加外来控件:
在工具箱中添加新的选项卡,右键添加选择项,浏览选择控件dll确定,引用控件即可添加到工具箱中。

枚举所有的摄像头:

[C#] 纯文本查看 复制代码
FilterInfoCollection videoDevices;videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
foreach (FilterInfo device in videoDevices)
                {
                    //可以做出处理
                }

连接摄像头:

声明:FileterInfo info;

[C#] 纯文本查看 复制代码
info = videoDevices[0];//选取第一个,此处可作灵活改动

VideoCaptureDevice videoSource = new VideoCaptureDevice(videoDevices[info.MonikerString);           videoSource.DesiredFrameSize = new System.Drawing.Size(214, 281); 
videoSource.DesiredFrameRate = 1; 
videoSourcePlayer.VideoSource = videoSource;
videoSourcePlayer.Start();

关闭摄像头:
[C#] 纯文本查看 复制代码
videoSourcePlayer.SignalToStop(); [/font][/color][/align][/font][/color]videoSourcePlayer.WaitForStop();

拍照:
if (videoSourcePlayer.IsRunning)

                {
            string path = "e:\";

                    BitmapSource bitmapSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(                                    videoSourcePlayer.GetCurrentVideoFrame().GetHbitmap(),                                    IntPtr.Zero,                                     Int32Rect.Empty,                                    BitmapSizeOptions.FromEmptyOptions());                    PngBitmapEncoder pE = new PngBitmapEncoder();                    pE.Frames.Add(BitmapFrame.Create(bitmapSource));                    string picName = path + "paizhao" + ".jpg";                    if (File.Exists(picName))                    {                        File.Delete(picName);                    }                    using (Stream stream = File.Create(picName))                    {                        pE.Save(stream);                    }                }



项目中要求是摄像头处于监控状态,拍照后画面固定存储,不满意可以清空再次进行拍照,直到满意为止。
做法是在videoSourcePlayer的上面添加一个image控件,因为项目是WPF做的,所有照片显示只能添加image控件,有两点需要注意:
1)WPF引用winform控件需要使用WindowsFormsHost控件,所以监控视频和照片显示时是控件WindowsFormsHost和image控件的显示和隐藏,此处走了一段弯路所以记录下来。
2)image控件的source已经绑定,但是照片需要清空删除该照片资源,系统提示的大致意思是资源已经被占用无法删除。解决途径:
声明:BitmapImage bmi = new System.Windows.Media.Imaging.BitmapImage();

使用时:bmi.BgeinInit();
bmi.UriSource = new Uri(picName);
bmi.CacheOption = BitmapCacheOption.OnLoad;
bmi.EndInit();
绑定:this.image.Source = bmi;




windows .net(C#+MSSQL) linux(php+mysql)  
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|软件编程 Inc.  

GMT+8, 2017-9-22 19:49 , Processed in 0.187000 second(s), 22 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表