silverlight4:摄像头占用状态检测以及二种截屏方法
时间:2022-04-23
本文章向大家介绍silverlight4:摄像头占用状态检测以及二种截屏方法,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
状态检测主要包括二个方面:是否安装了摄像头,摄像头是否被其它程序占用
视频截图有二种方法:一是直接利用CaptureSource类的CaptureImageAsync异步截屏,另一种是直接利用WriteableBitmap截屏幕,二种截屏方法的区别在于,CaptureImageAsync始终截的是视频原始内容,而直接用WriteableBitmap对指定区域截屏时,如果视频上面还有其它控件(比如TextBlock),最终截下的图会有其它内容叠在上面(如下图)
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中使用摄像头时,提示用户是否同意使用摄像头的界面中多出了一个"记住我"的选项
这个功能本来是想方便用户,不必每次都提示用户选择,但是也有一个副作用:比如第一次选择时,如果您不小心勾中了"Remember my answer"并选择了"No",那么以后系统会直接拒绝使用摄像头设备,而且没有任何提示!
当然也可以右击,在silverlight选项里去掉这种错误的记忆(如下图)
但问题是:用户很有可能不知道从哪里进入这个界面,所以我个人觉得如果当silverlight了自动记住了"禁止使用摄像头"时,是否能给个提示?这样会显得更友好一些
最后,从技术上讲silverlight 4的摄像头还有一个功能不如flash做得贴心,flash中摄像头有activity事件可以用来监听摄像头是否有活动,而silverlight中没有。这在某些领域中很有用,比如监控系统中经常需要判断摄像头对着的是不是一个静止不动的物体。(当然sl中变相的办法可以通过不断截屏然后比较二张图的差异,但这毕竟太麻烦了,不知道正式版中是不是会有所改进)
- web前端之锋利的jQuery八:jQuery插件的使用(表单验证、表单提交)
- 优化算法——牛顿法(Newton Method)
- merge语句导致的CPU使用率过高的优化(r7笔记第4天)
- 由dual导致的一个潜在的监控问题(r7笔记第3天)
- 剑指Offer——编程题的Java实现
- Python中if __name__ == "__main__": 的作用
- 每周算法练习——大数的乘法问题
- Java基础-25(01)图形用户界面编程GUI
- 每周算法练习——n皇后问题
- dg broker配置的问题及分析 (r7笔记第22天)
- 备库搭建中的一波三折(r7笔记第21天)
- Java基础-25(02)图形用户界面编程GUI
- 每周算法练习——最近对问题
- Java基础-25(03)图形用户界面编程GUI
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法