How To Scan QRCode For UWP (2)
这篇随笔主要介绍照相预览功能,重要使用的是MediaCapture对象,MediaCapture对象还可以用来处理录音和录制视频,本文只讨论照相功能。
1:查找摄像头
后置摄像头优先,找不到后置摄像头就返回找到的可用的摄像头列表的第一个。
/// <summary>
/// Queries the available video capture devices to try and find one mounted on the desired panel.
/// </summary>
/// <param name="desiredPanel">The panel on the device that the desired camera is mounted on.</param>
/// <returns>A DeviceInformation instance with a reference to the camera mounted on the desired panel if available,
/// any other camera if not, or null if no camera is available.</returns>
private static async Task<DeviceInformation> FindCameraDeviceByPanelAsync(Windows.Devices.Enumeration.Panel desiredPanel)
{
// Get available devices for capturing pictures.
var allVideoDevices = await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture); // Get the desired camera by panel.
DeviceInformation desiredDevice = allVideoDevices.FirstOrDefault(x => x.EnclosureLocation != null && x.EnclosureLocation.Panel == desiredPanel); // If there is no device mounted on the desired panel, return the first device found.
return desiredDevice ?? allVideoDevices.FirstOrDefault();
}
2:初始Camera
首先需要创建一个MediaCapture实例,MediaCapture类位于Windows.Media.Capture命名空间。然后需要允许App访问Camera,需要修改Package.appxmanifest文件,选择Capabilities Tab 勾选中 Microphone & Webcam。 调用MediaCapture.InitializeAsync方法并指定要初始化上一步找到的Camera。
如果MediaCapture使用的过程中抛出了Error,此时就需要释放MediaCapture资源,可以在MediaCapture的Failed事件来处理。
此外还使用了isInitialized 标志位来判断是否已经成功初始化了Camera。
3:预览
需要调用MediaCapture.StartPreviewAsync(),在预览过程中使用了DisplayRequest对象RequestActive方法来防止设备屏幕休眠。
同样使用了isPreviewing来判断Camera是否处于预览状态。
经过三个步骤后,就可以正常预览Camera了。
MediaCapture对象的StopPreviewAsync方法用来停止预览,停止预览后,设备就可以允许睡眠了,需要调用DisplayRequest对象RequestRelease。
4:其他
当App转换为Suspending状态时,先使用SuspendingOperation.GetDeferral()请求延迟挂起操作,释放完MediaCapture资源,最后调用SuspendingDeferral.Complete() 通知操作系统App已经准好被挂起了。当App转换为Resuming状态时,需要再次开启Camera。
可以分别处理Application.Current.Suspending跟Application.Current.Resuming事件。
附上代码:
using System;
using System.Linq;
using System.Threading.Tasks;
using Windows.ApplicationModel;
using Windows.Devices.Enumeration;
using Windows.Media.Capture;
using Windows.System.Display;
using Windows.UI.Core;
using Windows.UI.Popups;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation; // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 namespace ScanQRCode
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
const int borderThickness = ; private MediaCapture mediaCapture;
private bool isInitialized = false;
private bool isPreviewing = false; // Prevent the screen from sleeping while the camera is running.
private readonly DisplayRequest displayRequest = new DisplayRequest(); public MainPage()
{
this.InitializeComponent(); // Useful to know when to initialize/clean up the camera
Application.Current.Suspending += Application_Suspending;
Application.Current.Resuming += Application_Resuming;
} /// <summary>
/// Occures on app suspending. Stops camera if initialized.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private async void Application_Suspending(object sender, SuspendingEventArgs e)
{
// Handle global application events only if this page is active.
if (Frame.CurrentSourcePageType == typeof(MainPage))
{
var deferral = e.SuspendingOperation.GetDeferral(); await CleanupCameraAsync(); deferral.Complete();
}
} /// <summary>
/// Occures on app resuming. Initializes camera if available.
/// </summary>
/// <param name="sender"></param>
/// <param name="o"></param>
private async void Application_Resuming(object sender, object o)
{
// Handle global application events only if this page is active
if (Frame.CurrentSourcePageType == typeof(MainPage))
{
await StartCameraAsync();
}
} private void InitFocusRec()
{
leftTopBorder.BorderThickness = new Thickness(borderThickness, borderThickness, , );
rightTopBorder.BorderThickness = new Thickness(, borderThickness, borderThickness, );
leftBottomBorder.BorderThickness = new Thickness(borderThickness, , , borderThickness);
rightBottomBorder.BorderThickness = new Thickness(, , borderThickness, borderThickness); var borderLength = ;
leftTopBorder.Width = leftTopBorder.Height = borderLength;
rightTopBorder.Width = rightTopBorder.Height = borderLength;
leftBottomBorder.Width = leftBottomBorder.Height = borderLength;
rightBottomBorder.Width = rightBottomBorder.Height = borderLength; var focusRecLength = Math.Min(ActualWidth / , ActualHeight / );
scanGrid.Width = scanGrid.Height = focusRecLength;
scanCavas.Width = scanCavas.Height = focusRecLength; scanStoryboard.Stop();
scanLine.X2 = scanCavas.Width - ;
scanAnimation.To = scanCavas.Height; scanStoryboard.Begin();
} private void Page_SizeChanged(object sender, SizeChangedEventArgs e)
{
InitFocusRec();
} protected override async void OnNavigatedTo(NavigationEventArgs e)
{
await StartCameraAsync();
} private async Task StartCameraAsync()
{
if (!isInitialized)
{
await InitializeCameraAsync();
} if (isInitialized)
{
PreviewControl.Visibility = Visibility.Visible;
}
} /// <summary>
/// Queries the available video capture devices to try and find one mounted on the desired panel.
/// </summary>
/// <param name="desiredPanel">The panel on the device that the desired camera is mounted on.</param>
/// <returns>A DeviceInformation instance with a reference to the camera mounted on the desired panel if available,
/// any other camera if not, or null if no camera is available.</returns>
private static async Task<DeviceInformation> FindCameraDeviceByPanelAsync(Windows.Devices.Enumeration.Panel desiredPanel)
{
// Get available devices for capturing pictures.
var allVideoDevices = await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture); // Get the desired camera by panel.
DeviceInformation desiredDevice = allVideoDevices.FirstOrDefault(x => x.EnclosureLocation != null && x.EnclosureLocation.Panel == desiredPanel); // If there is no device mounted on the desired panel, return the first device found.
return desiredDevice ?? allVideoDevices.FirstOrDefault();
} /// Initializes the MediaCapture
/// </summary>
private async Task InitializeCameraAsync()
{
if (mediaCapture == null)
{
// Attempt to get the back camera if one is available, but use any camera device if not.
var cameraDevice = await FindCameraDeviceByPanelAsync(Windows.Devices.Enumeration.Panel.Back); if (cameraDevice == null)
{
//No camera device!
return;
} // Create MediaCapture and its settings.
mediaCapture = new MediaCapture(); // Register for a notification when something goes wrong
mediaCapture.Failed += MediaCapture_Failed; var settings = new MediaCaptureInitializationSettings { VideoDeviceId = cameraDevice.Id }; // Initialize MediaCapture
try
{
await mediaCapture.InitializeAsync(settings);
isInitialized = true;
}
catch (UnauthorizedAccessException)
{
await ShowMessage("Denied access to the camera.");
}
catch (Exception ex)
{
await ShowMessage("Exception when init MediaCapture. " + ex.Message);
} // If initialization succeeded, start the preview.
if (isInitialized)
{
await StartPreviewAsync();
}
}
} /// <summary>
/// Starts the preview after making a request to keep the screen on and unlocks the UI.
/// </summary>
private async Task StartPreviewAsync()
{
// Prevent the device from sleeping while the preview is running.
displayRequest.RequestActive(); // Set the preview source in the UI.
PreviewControl.Source = mediaCapture;
// Start the preview.
try
{
await mediaCapture.StartPreviewAsync();
isPreviewing = true;
}
catch (Exception ex)
{
await ShowMessage("Exception starting preview." + ex.Message);
}
} /// <summary>
/// Handles MediaCapture failures. Cleans up the camera resources.
/// </summary>
/// <param name="sender"></param>
/// <param name="errorEventArgs"></param>
private async void MediaCapture_Failed(MediaCapture sender, MediaCaptureFailedEventArgs errorEventArgs)
{
await CleanupCameraAsync();
} /// <summary>
/// Cleans up the camera resources (after stopping the preview if necessary) and unregisters from MediaCapture events.
/// </summary>
private async Task CleanupCameraAsync()
{
if (isInitialized)
{
if (isPreviewing)
{
// The call to stop the preview is included here for completeness, but can be
// safely removed if a call to MediaCapture.Dispose() is being made later,
// as the preview will be automatically stopped at that point
await StopPreviewAsync();
} isInitialized = false;
} if (mediaCapture != null)
{
mediaCapture.Failed -= MediaCapture_Failed;
mediaCapture.Dispose();
mediaCapture = null;
}
} /// <summary>
/// Stops the preview and deactivates a display request, to allow the screen to go into power saving modes, and locks the UI
/// </summary>
/// <returns></returns>
private async Task StopPreviewAsync()
{
try
{
isPreviewing = false;
await mediaCapture.StopPreviewAsync();
}
catch (Exception ex)
{
// Use the dispatcher because this method is sometimes called from non-UI threads.
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
{
await ShowMessage("Exception stopping preview. " + ex.Message);
});
} // Use the dispatcher because this method is sometimes called from non-UI threads.
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
PreviewControl.Source = null; // Allow the device to sleep now that the preview is stopped.
displayRequest.RequestRelease();
});
} private async Task ShowMessage(string message)
{
var messageDialog = new MessageDialog(message);
await messageDialog.ShowAsync();
}
}
}
How To Scan QRCode For UWP (2)的更多相关文章
- How To Scan QRCode For UWP (4)
QR Code的全称是Quick Response Code,中文翻译为快速响应矩阵图码,有关它的简介可以查看维基百科. 我准备使用ZXing.Net来实现扫描二维码的功能,ZXing.Net在Cod ...
- How To Scan QRCode For UWP (3)
这一节主要介绍如何去设置MediaCapture拍照的分辨率. MediaCapture 包含一个 VideoDeviceController对象,凭借它可以控制摄像头的很多设置,其中包括设置拍照的分 ...
- How To Scan QRCode For UWP (1)
本文将介绍实现一个类似于微信扫一扫功能的UI界面,后续会再实现具体的识别二维码的功能. 实例使用的Win10 SDK Version是Windows 10 Anniversary Edition(10 ...
- SWIFT Scan QRCode
SWIFT中扫描QRCode代码如下,照着敲一次再看下API的注释应该就没问题了. import UIKit import Foundation import AVFoundation class V ...
- Python生成二维码脚本
简单的记录下二维码生成和解析的Python代码 依赖下面三个包: PIL(图像处理包,安装:pip install PIL) qrcode(二维码生成包,安装:pip install qrcode) ...
- 初涉扫码登录:edusoho实现客户端扫码登录(简版)
一.项目简介及需求 edusoho是一套商业版的在线教育平台,项目本身基于symfony2框架开发,现在有一款自己的APP,要求在不多修改edusoho自身代码的基础上,实现客户端对PC端扫码登录.不 ...
- 一次使用Python连接数据库生成二维码并安装为windows服务的工作任务
最近有一个需求,在现有生产系统上的人员库中增加一个此人员关键信息的二维码,支持文字版和跳转版两种方式,与报表工具关联,可打印.以windows服务方式,定时检查,只要发现某人员没有此二维码信息,就生成 ...
- python库使用整理
1. 环境搭建 l Python安装包:www.python.org l Microsoft Visual C++ Compiler for Python l pip(get-pip.py):p ...
- AppCan移动应用开发平台新增9个超有用插件(内含演示样例代码)
使用AppCan平台进行移动开发.你所须要具备的是Html5+CSS +JS前端语言基础.此外.Hybrid混合模式应用还需结合原生语言对功能模块进行封装,对于没有原生基础的开发人员,怎样实现App里 ...
随机推荐
- redis概览
Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,和Memcached类似,它支持存储的value类型相对更多,包括string(字符串 ...
- 好文推荐系列--------(2)GruntJS——重复乏味的工作总会有人做(反正我不做)
GruntJS 是基于JavaScript的命令行构建工具,它可以帮助开发者们自动化重复性的工作.你可以把它看成是JavaScript下的Make或者Ant.它可以完成诸如精简.编译.单元测试.lin ...
- ★ prototype、__proto__ 详解
# var Person = function(name) { this.name = name; } var p = new Person(); //new操作符的操作是 var p = {} p. ...
- Simultaneous Localization and Mapping Technology Based on Project Tango
Abstract: Aiming at the problem of system error and noise in simultaneous localization and mapping ( ...
- eclipse查看方法被那些代码调用open call hierarchy
当我们编写的代码量十分巨大,项目十分复杂的时候,想要查找某一个方法都被其他那些代码调用了是一件十分困难的事,然后Eclipse提供了十分方便的方法用于查看方法都被那些代码调用了. 方法一: 选中要查看 ...
- sublime text配置node.js调试
1. 首先到 nodejs.org 下载 Node.js 安装包并安装.2. 打开 Sublime Text 2 编辑器.选择菜单 Tools --> Build System --> n ...
- hive sql 查询一张表的数据不在另一张表中
有时,我们需要对比两张表的数据,找到在其中一张表,不在另一张表中的数据 hql 如下: SELECT * FROM (SELECT id FROM a WHERE dt = '2019-03-17' ...
- http://vjudge.net/contest/view.action?cid=51142#problem/C 精度转换的一道题。。。
C - Get-Together at Den's Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & ...
- 3.Django视图
视图 视图接受Web请求并且返回Web响应 视图就是一个python函数,被定义在views.py中 响应可以是一张网页的HTML内容,一个重定向,一个404错误等等 响应处理过程如下图: URLco ...
- hog行人检测
本文主要介绍下opencv中怎样使用hog算法,因为在opencv中已经集成了hog这个类.其实使用起来是很简单的,从后面的代码就可以看出来.本文参考的资料为opencv自带的sample. 关于op ...