这篇随笔主要介绍照相预览功能,重要使用的是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. Lyft Level 5 Challenge 2018 - Final Round (Open Div. 2) C. The Tower is Going Home(思维+双指针)

    https://codeforces.com/contest/1075/problem/C 题意 一个宽为1e9*1e9的矩阵中的左下角,放置一个车(车可以移动到同一行或同一列),放置一些墙,竖的占据 ...

  2. git只合并某一个分支的某个commit

    第一种情况:只合并一个commit git checkout develop-hbb git cherry-pick 7c32be61 以上,7c32be61是develop上的一个fix bug的c ...

  3. VHDL基础2

    Signals & Variables VHDL 提供了 signal 和 variable 两种对象来处理非静态数据:提供了 constant 和 generic 来处理静态数据. cons ...

  4. 【repost】JavaScript运动框架之速度时间版本

    一.JavaScript运动框架之速度版 1.1 运动框架的实现思路 运动,其实就是在一段时间内改变 left . right . width . height . opactiy 的值,到达目的地之 ...

  5. android PendingIntent 使用通知传递多个参数,及不覆盖的问题

    Intent updateIntent = new Intent(GetNoticeService.this, DetailGonggaoActivity.class); updateIntent.p ...

  6. Linux 修改默认的 yum 源

    官方的yum源在国内访问效果不佳. 需要改为国内比较好的阿里的 yum源,因为每次装的时候都得百度,所以这里记录一下. 修改方式: 1)cd /etc/yum.repos.d/ 这个目录下普通用户可能 ...

  7. vmtools是灰色不可用的

  8. 9.js入门

    1.Js介绍 ◆js是一款运行在客户端的网页编程语言. ◆组成部分 ★ecmascript js标准 ★dom 通过js操作网页元素 ★bom 通过api操作浏览器 ◆特点 ★简单易用 ★解释执行 ★ ...

  9. Beta版本冲刺准备

    1. 介绍小组新加入的成员,Ta担任的角色. 姓名 王华俊 爱好 PS ,听音乐等等 编程方向 Java小程序,GUI 团队内担任的角色 美工 让他担任这个角色的理由:不同于别人的直男审美 2. 讨论 ...

  10. SSD 相关基础知识

    SDD 基础知识 SSD(Solid State Drives)是固态硬盘,使用闪存颗粒来存储数据,闪存又可分为NAND Flash和NOR Flash,通常所说的SSD硬盘都使用NAND Flash ...