这篇随笔主要介绍照相预览功能,重要使用的是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)的更多相关文章

  1. How To Scan QRCode For UWP (4)

    QR Code的全称是Quick Response Code,中文翻译为快速响应矩阵图码,有关它的简介可以查看维基百科. 我准备使用ZXing.Net来实现扫描二维码的功能,ZXing.Net在Cod ...

  2. How To Scan QRCode For UWP (3)

    这一节主要介绍如何去设置MediaCapture拍照的分辨率. MediaCapture 包含一个 VideoDeviceController对象,凭借它可以控制摄像头的很多设置,其中包括设置拍照的分 ...

  3. How To Scan QRCode For UWP (1)

    本文将介绍实现一个类似于微信扫一扫功能的UI界面,后续会再实现具体的识别二维码的功能. 实例使用的Win10 SDK Version是Windows 10 Anniversary Edition(10 ...

  4. SWIFT Scan QRCode

    SWIFT中扫描QRCode代码如下,照着敲一次再看下API的注释应该就没问题了. import UIKit import Foundation import AVFoundation class V ...

  5. Python生成二维码脚本

    简单的记录下二维码生成和解析的Python代码 依赖下面三个包: PIL(图像处理包,安装:pip install PIL) qrcode(二维码生成包,安装:pip install qrcode) ...

  6. 初涉扫码登录:edusoho实现客户端扫码登录(简版)

    一.项目简介及需求 edusoho是一套商业版的在线教育平台,项目本身基于symfony2框架开发,现在有一款自己的APP,要求在不多修改edusoho自身代码的基础上,实现客户端对PC端扫码登录.不 ...

  7. 一次使用Python连接数据库生成二维码并安装为windows服务的工作任务

    最近有一个需求,在现有生产系统上的人员库中增加一个此人员关键信息的二维码,支持文字版和跳转版两种方式,与报表工具关联,可打印.以windows服务方式,定时检查,只要发现某人员没有此二维码信息,就生成 ...

  8. python库使用整理

    1. 环境搭建 l  Python安装包:www.python.org l  Microsoft Visual C++ Compiler for Python l  pip(get-pip.py):p ...

  9. AppCan移动应用开发平台新增9个超有用插件(内含演示样例代码)

    使用AppCan平台进行移动开发.你所须要具备的是Html5+CSS +JS前端语言基础.此外.Hybrid混合模式应用还需结合原生语言对功能模块进行封装,对于没有原生基础的开发人员,怎样实现App里 ...

随机推荐

  1. 阿里云存储oss+怎么上传找文件夹

    最近公司做工程项目,实现文件夹云存储上传. 网上找了很久,发现网上很多项目都存在相似问题,最后终于找到了一个符合我要求的项目. 工程如下: 这里对项目的文件夹云存储上传进行分析,实现文件夹上传,如何进 ...

  2. docker 搭建 MYSQL并且完成主从复制

    mysql主从复制逻辑: 1.从库执行start slave 开启主从复制. 2.从库请求连接到主库,并且指定binlog文件以及位置后发出请求. 3.主库收到从库请求后,将信息返回给从库,除了信息日 ...

  3. 笔记:使用mailto在网页中链接Email地址

    <a>标签还有一个作用是可以链接Email地址,使用mailto能让访问者便捷向网站管理者发送电子邮件.我们还可以利用mailto做许多其它事情.下面一一进行讲解,请看详细图示: 注意:如 ...

  4. gcc和vs在c的一些区别

    1.switch中每个标签后面的命令在gcc中需要{}括起来以指明作用域. 2._itoa是非标准的c和c++扩展函数,在linux下可以使用sprintf(string,   "%d &q ...

  5. kepware http接口 c语言 python

    读取某变量的值(http.client import http.client conn = http.client.HTTPConnection("127,0,0,1") head ...

  6. 【python-ini】python读写ini文件

    [python-ini]python读写ini文件 本文实例讲述了Python读写ini文件的方法.分享给大家供大家参考.具体如下: 比如有一个文件update.ini,里面有这些内容:   1 2 ...

  7. redis链接

    参考资料:http://www.runoob.com/redis/redis-connection.htmlRedis 连接Redis 连接命令主要是用于连接 redis 服务.实例以下实例演示了客户 ...

  8. 关于FPGA的一些小见解

    Xilinx FPGA配置bit流文件 Xilinx FPGA的供电是采用USB作为电源,使用Verilog HDL或VHDL实现的逻辑电路通过Xilinx的综合工具生成bit流文件,通过Digile ...

  9. [kuangbin]树链剖分A - Aragorn's Story

    比较水的题了,比模板题还要简单一点 理解了这个结构,自己打出来的,但是小错误还是很多,越来越熟练吧希望 错误函数updata,updata_lca,query||错误地方区间往下递归的时候是left ...

  10. 安装sublime3

    Sublime-text-3的安装步骤1添加Sublime-text-3软件包的软件源sudo add-apt-repository ppa:webupd8team/sublime-text-3 2使 ...