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

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

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

Xaml部分代码:

01 <UserControl x:Class="CameraCheck.MainPage"
06     mc:Ignorable="d"
07     >
08     <Grid x:Name="LayoutRoot" Background="White"
09         <Grid.RowDefinitions>
10             <RowDefinition Height="162"></RowDefinition>
11             <RowDefinition Height="190"></RowDefinition>
12         </Grid.RowDefinitions>
13         <StackPanel Grid.Row="0">   
14             <Canvas Height="120" Width="160" HorizontalAlignment="Center" x:Name="cVideo" Margin="0,10,0,10">
15                 <Rectangle Width="160" Height="120" x:Name="rectVideo" StrokeThickness="1" Stroke="Black"></Rectangle>
16                 <TextBlock x:Name="lblStatus" Text="菩提树下的杨过"  Foreground="White" Canvas.Top="50" Width="160" TextAlignment="Center"></TextBlock>
17             </Canvas>            
18             <StackPanel  Orientation="Horizontal" HorizontalAlignment="Center">
19                 <Button Width="80" Height="22" Content="检测摄像头" x:Name="btnCheck" Click="btnCheck_Click"></Button>
20                 <Button Width="80" Height="22" Content="视频原始截图" x:Name="btnCapture1" Margin="5,0,0,0" Click="btnCapture1_Click"></Button>
21                 <Button Width="80" Height="22" Content="bitmap截图" x:Name="btnCapture2" Margin="5,0,0,0" Click="btnCapture2_Click"></Button>
22             </StackPanel>            
23         </StackPanel>
24           
25         <ScrollViewer x:Name="imgList" Height="180" HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Hidden" Margin="0,10,0,0" Grid.Row="1">
26             <StackPanel x:Name="sp" Orientation="Horizontal"></StackPanel>
27         </ScrollViewer>
28     </Grid>
29 </UserControl>

后端CS代码:

001 using System.Windows;
002 using System.Windows.Controls;
003 using System.Windows.Media;
004 using System.Windows.Media.Imaging;
005   
006   
007 namespace CameraCheck
008 {
009     public partial class MainPage : UserControl
010     {
011         bool _isWorked = false;
012         CaptureSource _webCamSource;
013   
014         public MainPage()
015         {
016             InitializeComponent();
017         }
018   
019         private void btnCheck_Click(object sender, RoutedEventArgs e)
020         {
021             if (_isWorked) { return; }
022   
023             VideoCaptureDevice webCam = CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice();
024   
025             if (webCam == null
026             {
027                 lblStatus.Text = "未检测到摄像头设备!";
028                 return;
029             }
030   
031             if (CaptureDeviceConfiguration.RequestDeviceAccess())
032             {
033                 _webCamSource = new CaptureSource();
034                 _webCamSource.VideoCaptureDevice = webCam;
035                 VideoBrush video = new VideoBrush();
036                 video.SetSource(_webCamSource);
037                 video.Stretch = Stretch.UniformToFill;               
038                 try
039                 {
040                     _webCamSource.Start();                   
041                     this.rectVideo.Fill = video;
042                     lblStatus.Text = "摄像头正在工作中...";//测试用
043                     _isWorked = true;
044                     _webCamSource.CaptureFailed += webCamSource_CaptureFailed;
045                     _webCamSource.CaptureImageCompleted += webCamSource_CaptureImageCompleted;
046                 }
047                 catch 
048                 {
049                     lblStatus.Text = "摄像头无法使用(可能被占用)";
050                 }                
051             }
052             else 
053             {
054                 lblStatus.Text = "您不同意在本程序\n中使用摄像头设备.";
055             }
056         }
057   
058         /// <summary>
059         /// CaptureImageAsync视频原始内容截图
060         /// </summary>
061         /// <param name="sender"></param>
062         /// <param name="e"></param>
063         private void btnCapture1_Click(object sender, RoutedEventArgs e)
064         {           
065             if (_isWorked)
066             {               
067                 _webCamSource.CaptureImageAsync();
068             }
069         }
070   
071   
072         void webCamSource_CaptureImageCompleted(object sender, CaptureImageCompletedEventArgs e)
073         {
074             WriteableBitmap wb = e.Result;            
075             Image image = new Image();
076             image.Height = 120;
077             image.Margin = new Thickness(5);
078             image.Source = wb;
079             sp.Children.Add(image);            
080         }
081   
082         void webCamSource_CaptureFailed(object sender, ExceptionRoutedEventArgs e)
083         {
084             lblStatus.Text = "截屏失败!";
085         }
086   
087         /// <summary>
088         /// 利用WriteableBitmap截屏
089         /// </summary>
090         /// <param name="sender"></param>
091         /// <param name="e"></param>
092         private void btnCapture2_Click(object sender, RoutedEventArgs e)
093         {
094             WriteableBitmap wb = new WriteableBitmap(cVideo, null);
095             Image image = new Image();
096             image.Height = 120;
097             image.Margin = new Thickness(5);
098             image.Source = wb;
099             sp.Children.Add(image);
100         }
101   
102   
103     }
104 }

另外silverlight 4中使用摄像头时,提示用户是否同意使用摄像头的界面中多出了一个"记住我"的选项

这个功能本来是想方便用户,不必每次都提示用户选择,但是也有一个副作用:比如第一次选择时,如果您不小心勾中了"Remember my answer"并选择了"No",那么以后系统会直接拒绝使用摄像头设备,而且没有任何提示!

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

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

 

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

作者:菩提树下的杨过
出处:http://yjmyzz.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
posted @ 2010-03-19 09:29  周宏伟  阅读(704)  评论(0)    收藏  举报