silverlight4:摄像头占用状态检测以及二种截屏方法

简介: 状态检测主要包括二个方面:是否安装了摄像头,摄像头是否被其它程序占用 视频截图有二种方法:一是直接利用CaptureSource类的CaptureImageAsync异步截屏,另一种是直接利用WriteableBitmap截屏幕,二种截屏方法的区别在于,CaptureImageAsync始终截的是...

状态检测主要包括二个方面:是否安装了摄像头,摄像头是否被其它程序占用

视频截图有二种方法:一是直接利用CaptureSource类的CaptureImageAsync异步截屏,另一种是直接利用WriteableBitmap截屏幕,二种截屏方法的区别在于,CaptureImageAsync始终截的是视频原始内容,而直接用WriteableBitmap对指定区域截屏时,如果视频上面还有其它控件(比如TextBlock),最终截下的图会有其它内容叠在上面(如下图)
img_696d92ecc09644841f2bc5fb8ea074fa.jpg 

Xaml部分代码:

<UserControl x:Class="CameraCheck.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"
    >
    <Grid x:Name="LayoutRoot" Background="White"> 
        <Grid.RowDefinitions>
            <RowDefinition Height="162"></RowDefinition>
            <RowDefinition Height="190"></RowDefinition>
        </Grid.RowDefinitions>
        <StackPanel Grid.Row="0">   
            <Canvas Height="120" Width="160" HorizontalAlignment="Center" x:Name="cVideo" Margin="0,10,0,10">
                <Rectangle Width="160" Height="120" x:Name="rectVideo" StrokeThickness="1" Stroke="Black"></Rectangle>
                <TextBlock x:Name="lblStatus" Text="菩提树下的杨过"  Foreground="White" Canvas.Top="50" Width="160" TextAlignment="Center"></TextBlock>
            </Canvas>            
            <StackPanel  Orientation="Horizontal" HorizontalAlignment="Center">
                <Button Width="80" Height="22" Content="检测摄像头" x:Name="btnCheck" Click="btnCheck_Click"></Button>
                <Button Width="80" Height="22" Content="视频原始截图" x:Name="btnCapture1" Margin="5,0,0,0" Click="btnCapture1_Click"></Button>
                <Button Width="80" Height="22" Content="bitmap截图" x:Name="btnCapture2" Margin="5,0,0,0" Click="btnCapture2_Click"></Button>
            </StackPanel>            
        </StackPanel>
        
        <ScrollViewer x:Name="imgList" Height="180" HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Hidden" Margin="0,10,0,0" Grid.Row="1">
            <StackPanel x:Name="sp" Orientation="Horizontal"></StackPanel>
        </ScrollViewer>
    </Grid>
</UserControl>

后端CS代码:

using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;


namespace CameraCheck
{
    public partial class MainPage : UserControl
    {
        bool _isWorked = false;
        CaptureSource _webCamSource;

        public MainPage()
        {
            InitializeComponent();
        }

        private void btnCheck_Click(object sender, RoutedEventArgs e)
        {
            if (_isWorked) { return; }

            VideoCaptureDevice webCam = CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice();

            if (webCam == null) 
            {
                lblStatus.Text = "未检测到摄像头设备!";
                return;
            }

            if (CaptureDeviceConfiguration.RequestDeviceAccess())
            {
                _webCamSource = new CaptureSource();
                _webCamSource.VideoCaptureDevice = webCam;
                VideoBrush video = new VideoBrush();
                video.SetSource(_webCamSource);
                video.Stretch = Stretch.UniformToFill;               
                try
                {
                    _webCamSource.Start();                   
                    this.rectVideo.Fill = video;
                    lblStatus.Text = "摄像头正在工作中...";//测试用
                    _isWorked = true;
                    _webCamSource.CaptureFailed += webCamSource_CaptureFailed;
                    _webCamSource.CaptureImageCompleted += webCamSource_CaptureImageCompleted;
                }
                catch 
                {
                    lblStatus.Text = "摄像头无法使用(可能被占用)";
                }                
            }
            else 
            {
                lblStatus.Text = "您不同意在本程序\n中使用摄像头设备.";
            }
        }

        /// <summary>
        /// CaptureImageAsync视频原始内容截图
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnCapture1_Click(object sender, RoutedEventArgs e)
        {           
            if (_isWorked)
            {               
                _webCamSource.CaptureImageAsync();
            }
        }


        void webCamSource_CaptureImageCompleted(object sender, CaptureImageCompletedEventArgs e)
        {
            WriteableBitmap wb = e.Result;            
            Image image = new Image();
            image.Height = 120;
            image.Margin = new Thickness(5);
            image.Source = wb;
            sp.Children.Add(image);            
        }

        void webCamSource_CaptureFailed(object sender, ExceptionRoutedEventArgs e)
        {
            lblStatus.Text = "截屏失败!";
        }

        /// <summary>
        /// 利用WriteableBitmap截屏
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnCapture2_Click(object sender, RoutedEventArgs e)
        {
            WriteableBitmap wb = new WriteableBitmap(cVideo, null);
            Image image = new Image();
            image.Height = 120;
            image.Margin = new Thickness(5);
            image.Source = wb;
            sp.Children.Add(image);
        }


    }
}

另外silverlight 4中使用摄像头时,提示用户是否同意使用摄像头的界面中多出了一个"记住我"的选项
img_68e84a43c71db4b13bb8c8ecc543c82b.jpg
这个功能本来是想方便用户,不必每次都提示用户选择,但是也有一个副作用:比如第一次选择时,如果您不小心勾中了"Remember my answer"并选择了"No",那么以后系统会直接拒绝使用摄像头设备,而且没有任何提示!

当然也可以右击,在silverlight选项里去掉这种错误的记忆(如下图)
img_30a0c944be456cb6360a8264b82f3889.jpg

但问题是:用户很有可能不知道从哪里进入这个界面,所以我个人觉得如果当silverlight了自动记住了"禁止使用摄像头"时,是否能给个提示?这样会显得更友好一些

 

最后,从技术上讲silverlight 4的摄像头还有一个功能不如flash做得贴心,flash中摄像头有activity事件可以用来监听摄像头是否有活动,而silverlight中没有。这在某些领域中很有用,比如监控系统中经常需要判断摄像头对着的是不是一个静止不动的物体。(当然sl中变相的办法可以通过不断截屏然后比较二张图的差异,但这毕竟太麻烦了,不知道正式版中是不是会有所改进)

目录
相关文章
|
测试技术 程序员 C++
iOS:项目中无用类检测和无用图片检测汇总
在涉及到项目大改版,或者涉及到某个功能模块大变更,就会涉及到图片废弃和文件废弃的情况。 但是这时候就会遗留下一个很大的问题,没有将废弃的、无用的文件类或资源删除干净。而这次需要对工程代码的无用资源和无用文件进行删除处理,感触颇多,故在此笔记。 首先,感觉很多人的代码习惯还是恶待提高。比如我发现一些人的代码操作习惯,从好到次,可以大略分以下情况
1275 0
iOS:项目中无用类检测和无用图片检测汇总
|
4月前
|
算法 测试技术 计算机视觉
LabVIEW自动探头外观检测
LabVIEW自动探头外观检测
20 1
|
5月前
|
数据采集 人工智能 文字识别
ADB命令来捕获设备屏幕快照和发送鼠标事件来实现抓取公众号文章
ADB命令来捕获设备屏幕快照和发送鼠标事件来实现抓取公众号文章。解决方案: 1.通过ADB命令来捕获设备屏幕快照,传递给电脑并且保存在本地文件; 2.通过百度飞桨ocr解析图片获取内容并保存; 3.根据解析的内容和坐标,向手机发送鼠标事件(点击和上下,左右滑动)来控制页面的跳转。
100 1
|
前端开发 JavaScript API
几种不常用Web API(振动、重力感应、联网状态、系统电量信息、页面可见性、canvas转base64、监听屏幕旋转、元素全屏显示)
navigator对象中有一些不常用的API,以下主要介绍vibrate振动,deviceorientation重力感应,online联网状态,getBattery系统电量信息,visibilitychange页面可见性,toDataURL(canvas转base64),orientationchange监听屏幕旋转和fullScreen元素全屏显示。
几种不常用Web API(振动、重力感应、联网状态、系统电量信息、页面可见性、canvas转base64、监听屏幕旋转、元素全屏显示)
|
XML API 数据格式
最新高通 Vuforia 7.0.47 版本-对应API-动态加载、卸载识别库-闪光灯-对焦-翻转摄像头-动态更改识别数量等
整理了下Vuforia 7 版本对应识别功能的函数 基本上和6版本无差异 Vuforia版本获取 string vuforiaVersion = Vuforia.
1166 0
下一篇
无影云桌面