• Silverlight4Beta之操作摄像头/麦克风


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

    image

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

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

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

    老规矩,我们先造个简单UI出来,XAML如下

    <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="300">
        <TextBlock>
                <Run Text="视频设备名称:"/>
                <Run x:Name="txtCameraName"/>
        </TextBlock>
        <Border BorderBrush="Black" BorderThickness="2" Width="300" Height="200">
            <Rectangle x:Name="Container" >
    
            </Rectangle>
        </Border>
        <StackPanel Orientation="Horizontal">
            <Button Content="开始" x:Name="btnStart"/>
            <Button Content="停止" x:Name="btnStop"/>
            <Button Content="截屏" x:Name="btnCapture"/>
        </StackPanel>
        <Image x:Name="imgCapture" Width="100" Height="100"/>
    </StackPanel>

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

    image

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

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

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

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

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

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

    VideoCaptureDevice vcd ;

    vcd = CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice();

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

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

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

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

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

    image

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

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

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

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

    image

    它的Callback直接返回WriteableBitmap,可以直接作为Image的源,非常方便。

    最后让我们看下全部的后台代码

    public MainPage()
    {
        InitializeComponent();
        this.Loaded += new RoutedEventHandler(MainPage_Loaded);
        this.btnCapture.Click += new RoutedEventHandler(btnCapture_Click);
        this.btnStart.Click += new RoutedEventHandler(btnStart_Click);
        this.btnStop.Click += new RoutedEventHandler(btnStop_Click);
    }
    
    void btnStart_Click(object sender, RoutedEventArgs e)
    {
        if (CaptureDeviceConfiguration.AllowedDeviceAccess || CaptureDeviceConfiguration.RequestDeviceAccess())
        {
            source.Start();
        }
    }
    
    void btnStop_Click(object sender, RoutedEventArgs e)
    {
        source.Stop();
    }
    
    void btnCapture_Click(object sender, RoutedEventArgs e)
    {
        if (source.State == CaptureState.Started)
            source.AsyncCaptureImage((bitmap) => { imgCapture.Source = bitmap; });
    }
    
    void MainPage_Loaded(object sender, RoutedEventArgs e)
    {
        VideoCaptureDevice vcd = CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice();
        txtCameraName.Text = vcd.FriendlyName;
        CaptureSource source;
        source = new CaptureSource();
        source.VideoCaptureDevice = vcd;
        VideoBrush vb = new VideoBrush();
        vb.SetSource(source);
        Container.Fill = vb;
    }

    OK,大功告成!F5运行一下吧。

    下面请大家欣赏本人靓照。。

    image

  • 相关阅读:
    Java 线程池学习
    Java线程:新特征-线程池
    创建Java线程池
    JAVA-线程安全性
    java线程安全总结
    栈和队列
    历年题目
    蓝桥杯算法训练
    hdu2083 暴力水
    poj 2299
  • 原文地址:https://www.cnblogs.com/024hi/p/1640583.html
Copyright © 2020-2023  润新知