web 调用摄像头 Silverlight实现

本文一部分内容参照下面两地方:

http://www.cnblogs.com/024hi/archive/2010/01/06/1640583.html

http://msdn.microsoft.com/zh-cn/library/cc838218(v=vs.95).aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-7

最近要调查要用C# web调用调用摄像头。

看了一下大概三种方法:

1.可以使用在网页中嵌入拍照的flash的方法。
asp.net+flash实现拍照的例子:
http://download.csdn.net/source/860173

2.另外使用Silverlight也可以操作摄像头。
例子:
http://www.cnblogs.com/024hi/archive/2010/01/06/1640583.html

3.调用ActiveX控件的例子:
http://download.csdn.net/source/2395953

本文是上面的第二种方法,由于原文章不是很全,这不进行修正补充。

具体如下:

首先的要有Silverlight开发环境,没有的话参照Silverlight开发环境

Silverlight4Beta带来了万众期待的新特性:对摄像头/麦克风的支持。

image

本篇文章将通过一个操作摄像头的实例来演示这个新特性,我们的实例主要实现以下功能

  • 显示设备名
  • 开始/停止捕获视频
  • 实时截取图像

由于麦克风的使用和摄像头大同小异,并且也无法直观的表现所以在这里就不赘述了。

 

创建 Silverlight 项目

名称Silverlight_Camera;不会的请看:http://msdn.microsoft.com/zh-cn/library/cc838164(v=vs.95).aspx

先做个简单UI出来,XAML如下:

<UserControl x:Class="Silverlight_Camera.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400" Loaded="UserControl_Loaded">

    <!--<Grid x:Name="LayoutRoot" Background="White">

    </Grid>-->
    <UserControl.Resources>
    <Style  TargetType="TextBlock">
        <Setter Property="FontSize" Value="12"/>
        <Setter Property="FontFamily" Value="Arial,SimSun"/>
    </Style>
    <Style  TargetType="Button">
        <Setter Property="FontSize" Value="12"/>
        <Setter Property="FontFamily" Value="SimSun"/>
        <Setter Property="Margin" Value="5"/>
    </Style>
    </UserControl.Resources>
    <StackPanel x:Name="LayoutRoot" Width="700">
        <TextBlock>
            <Run Text="视频设备名称:"/>
            <Run x:Name="txtCameraName"/>
        </TextBlock>
        <Border BorderBrush="Black" BorderThickness="2" Width="640" Height="480">
            <Rectangle x:Name="Container" >

            </Rectangle>
        </Border>
        <StackPanel Orientation="Horizontal">
            <Button Content="开始" x:Name="btnStart" Click="btnStart_Click" />
            <Button Content="停止" x:Name="btnStop" Click="btnStop_Click" />
            <Button Content="截屏" x:Name="btnCapture" Click="btnCapture_Click" />
        </StackPanel>
        <Image x:Name="imgCapture" Width="640" Height="480"/>
    </StackPanel>
</UserControl>


 

按下F5,运行时的样子大概如此

image

其中txtCameraName用以显示当前设备(摄像头或麦克风)的名称

imgCapture是个Image控件,用在承载生成的截图。

Container是一个Rectangle,用以承载VideoBrush,也就是我们的摄像头影响反馈区。当然,这里并不局限使用Rectangle,凡是可以设置Brush的控件都可以,比如文字的Bursh用摄像头影像填充是不是很有意思呢(只不过没什么意义-_-),这就靠大家发挥想象了。

下面三个按钮分别负责启动摄像头、停止和截取当前影像。

好的,UI就是这么简单。接下来我们看关键的代码部分。

 public partial class MainPage : UserControl
    {
        /// <summary>
        /// CaptureSource对象用来显示摄像头图片
        /// </summary>
        CaptureSource source;

        /// <summary>
        /// 构造方法
        /// </summary>
        public MainPage()
        {
            InitializeComponent();
            this.Loaded += new RoutedEventHandler(UserControl_Loaded);
            this.btnCapture.Click += new RoutedEventHandler(btnCapture_Click);
            this.btnStart.Click += new RoutedEventHandler(btnStart_Click);
            this.btnStop.Click += new RoutedEventHandler(btnStop_Click);
        }

        /// <summary>
        /// 开始按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnStart_Click(object sender, RoutedEventArgs e)
        {
            if (CaptureDeviceConfiguration.AllowedDeviceAccess || CaptureDeviceConfiguration.RequestDeviceAccess())
            {
                source.Start();
            }
        }

        /// <summary>
        /// 停止按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnStop_Click(object sender, RoutedEventArgs e)
        {
            source.Stop();
        }

        /// <summary>
        /// 截屏按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnCapture_Click(object sender, RoutedEventArgs e)
        {
            if (source.VideoCaptureDevice != null && source.State == CaptureState.Started)
            {
                source.CaptureImageAsync();
            }

        }

        /// <summary>
        /// 页面加载
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            // 得到摄像头名称
            VideoCaptureDevice vcd = CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice();
            txtCameraName.Text = vcd.FriendlyName;

            //初始化CaptureSource
            source = new CaptureSource();

            // 设置捕捉图像事件
            source.CaptureImageCompleted += new
                EventHandler<CaptureImageCompletedEventArgs>(CaptureSource_CaptureImageCompleted);
            source.CaptureFailed +=
                new EventHandler<ExceptionRoutedEventArgs>(CaptureSource_CaptureFailed);
            // 设置设备
            source.VideoCaptureDevice = vcd;
            // 显示图像
            VideoBrush vb = new VideoBrush();
            vb.SetSource(source);
            Container.Fill = vb;
        }

        /// <summary>
        /// 捕捉图像成功
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void CaptureSource_CaptureImageCompleted(object sender, CaptureImageCompletedEventArgs e)
        {
            // Set the ImageBrush source (defined in XAML) to the Result property
            imgCapture.Source = e.Result;
        }

        /// <summary>
        /// 捕捉图像失败
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void CaptureSource_CaptureFailed(object sender, ExceptionRoutedEventArgs e)
        {
            // Handle the failure.
        }

    }

关键代码:

 

 //初始化CaptureSource
            source = new CaptureSource();

            // 设置捕捉图像事件
            source.CaptureImageCompleted += new
                EventHandler<CaptureImageCompletedEventArgs>(CaptureSource_CaptureImageCompleted);
            source.CaptureFailed +=
                new EventHandler<ExceptionRoutedEventArgs>(CaptureSource_CaptureFailed);
            // 设置设备
            source.VideoCaptureDevice = vcd;
            // 显示图像
            VideoBrush vb = new VideoBrush();
            vb.SetSource(source);


 

首先我们实例化一个CaptureSource,作为摄像头/麦克风源。它可以用做VideoBrush的Source。

然后我们要通过CaptureDeviceConfiguration类的静态方法:GetDefaultVideoCaptureDevice得到一个VideoCaptureDevice的实例。这个方法的作用是得到默认的视频设备。这与我们在文章最前面贴图中的默认设备设置有关。当然我们也可以得到所有的可用设备然后让用户自己选择---即通过GetAvailableVideoCaptureDevices()这个方法。

我们拿到实例后,将其赋给CaptureSource的VideoCaptureDevice属性。

至此,我们的准备工作就结束了,简单的很吧。

 

接下来操作摄像头就更简单了--通过CaptureSource的Start()和Stop()方法就可以。

这里要注意的是,Silverlight一贯的安全准则是针对敏感操作一定要经由用户触发以及同意。所以我们使用Start()或者Stop()方法时必须通过按钮或者其他的用户行为,而不能写在Loaded事件甚至构造函数中,这样就是用户有意触发的。然后是要经过用户同意,一个可以工作的摄像头操作程序准备启动摄像头时会有这样的提示:

image

当用户点击“Yes”的时候才视为用户同意启动摄像头/麦克风

因此,我们在启动摄像头/麦克风的代码中必须确认它是经过用户同意的,用代码说话就是:

if (CaptureDeviceConfiguration.AllowedDeviceAccess || 
    CaptureDeviceConfiguration.RequestDeviceAccess()) {
    //启动摄像头/麦克风以及其他操作
}

最后就是截屏功能了,我们可以使用CaptureSource的AsyncCaptureImage方法,看一下该方法的定义

        // Summary:
        //     Initiates an asynchronous image capture request. Retrieve the returned image
        //     by handling the System.Windows.Media.CaptureSource.CaptureImageCompleted
        //     event on this System.Windows.Media.CaptureSource.
        public void CaptureImageAsync();


上面就是所有代码


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

围观岳老师

雁过留音人过留名你鼓励为我动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值