How To Scan QRCode For UWP (4)
QR Code的全称是Quick Response Code,中文翻译为快速响应矩阵图码,有关它的简介可以查看维基百科。 我准备使用ZXing.Net来实现扫描二维码的功能,ZXing.Net在Codeplex上有介绍可以参考https://zxingnet.codeplex.com/。
可以通过Nuget来引入ZXing.uwp到项目中,解码QR code的API非常简单,如下所示:
public Result Decode(WriteableBitmap barcodeBitmap);
看上去实现解码功能很easy,只需要调用 LowLagPhotoCapture.CaptureAsync 获取Camera捕获的IRandomAccessStream对象,然后构造一个新的 WriteableBitmap 对象 调用WriteableBmp.SetSourceAsync 将捕获的流设置到 WriteableBitmap 里面。最后调用BarcodeReader.Decode来解码QR code。
然而事情往往并非那么顺利,拿着平板对着屏幕扫了半天,也不见能够Quick Response。看来下ZXing.Net写的实例代码,跟我写的没有啥区别,同样也是很难解码QR code。 接着我尝试去解码一个静态的二维码图片,发现成功率100%,而且成功解码出来都是毫秒级别的。于是我又尝试去调试了下Decode的实现源码,发现我拍照的图片分辨率是1920 * 1080,那张静态图片的分辨率是300 * 300。 于是我需要做的就是将拍照的图片进行裁剪,裁剪出来的图片的大小跟中间的那个框的大小差不多。关于如何去裁剪图片可以参考另外一片随笔 How To Crop Bitmap For UWP。
为了能方便测试反复扫描二维码,我还写了一个简单的ResultPage,就一个文本框显示解码后的文本,一个按钮点击继续扫描。
实现代码也是非常简单:
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation; namespace ScanQRCode
{
public sealed partial class ResultPage : Page
{
public ResultPage()
{
this.InitializeComponent();
} protected override void OnNavigatedTo(NavigationEventArgs e)
{
txtResult.Text = e.Parameter.ToString();
} private void btnScan_Click(object sender, RoutedEventArgs e)
{
Frame.Navigate(typeof(MainPage));
}
}
}
扫描二维码的具体实现代码如下:
private async Task StartScanQRCode()
{
try
{
Result _result = null;
while (_result == null && lowLagPhotoCapture != null && IsCurrentUIActive)
{
var capturedPhoto = await lowLagPhotoCapture.CaptureAsync();
if (capturedPhoto == null)
{
continue;
}
using (var stream = capturedPhoto.Frame.CloneStream())
{
//calculate the crop square's length.
var pixelWidth = capturedPhoto.Frame.Width;
var pixelHeight = capturedPhoto.Frame.Height;
var rate = Math.Min(pixelWidth, pixelHeight) / Math.Min(ActualWidth, ActualHeight);
var cropLength = focusRecLength * rate; // initialize with 1,1 to get the current size of the image
var writeableBmp = new WriteableBitmap(, );
var rect = new Rect(pixelWidth / - cropLength / ,
pixelHeight / - cropLength / , cropLength, cropLength);
using (var croppedStream = await ImageHelper.GetCroppedStreamAsync(stream, rect))
{
writeableBmp.SetSource(croppedStream);
// and create it again because otherwise the WB isn't fully initialized and decoding
// results in a IndexOutOfRange
writeableBmp = new WriteableBitmap((int)cropLength, (int)cropLength);
croppedStream.Seek();
await writeableBmp.SetSourceAsync(croppedStream);
} _result = ScanBitmap(writeableBmp);
}
} if (_result != null)
{
Frame.Navigate(typeof(ResultPage), _result.Text);
}
}
catch (Exception ex)
{
Debug.WriteLine("Exception when scaning QR code" + ex.Message);
}
} private Result ScanBitmap(WriteableBitmap writeableBmp)
{
var barcodeReader = new BarcodeReader
{
AutoRotate = true,
Options = { TryHarder = true }
}; return barcodeReader.Decode(writeableBmp);
}
在处理窗体VisibilityChanged/Application.Current.Suspending/OnNavigatedTo/OnNavigatedFrom事件引发的时候,需要很好控制是需要开启Camera还是要关闭销毁Camera。本示例主要靠IsCurrentUIActive属性来判断,当IsCurrentUIActive为false的时候不能去调用LowLagPhotoCapture.CaptureAsync,否则就会抛“ A media source cannot go from the stopped state to the paused state ”异常,之后又无法调用MediaCapture.StopPreviewAsync来停止预览。重新初始化MediaCapture,再次去调用LowLagPhotoCapture.CaptureAsync又会抛出“ Hardware MFT failed to start streaming due to lack of hardware resources ” 异常,因为之前没有停止。这个问题困扰了我一段时间。
实现代码:
private bool IsCurrentUIActive
{
// UI is active if
// * We are the current active page.
// * The window is visible.
// * The app is not suspending.
get { return _isActivePage && !_isSuspending && Window.Current.Visible; }
}
根据当前UI是否为Active来决定是启动Camera还是销毁Camera。
private async Task SwitchCameraOnUIStateChanged()
{
// Avoid reentrancy: Wait until nobody else is in this function.
while (!_setupTask.IsCompleted)
{
await _setupTask;
} if (_isUIActive != IsCurrentUIActive)
{
_isUIActive = IsCurrentUIActive; Func<Task> setupAsync = async () =>
{
if (IsCurrentUIActive)
{
await StartCameraAsync();
}
else
{
await CleanupCameraAsync();
}
};
_setupTask = setupAsync();
} await _setupTask;
}
完整代码已上传到github
https://github.com/supperwu/UWP_Simple/tree/master/ScanQRCode
How To Scan QRCode For UWP (4)的更多相关文章
- How To Scan QRCode For UWP (3)
这一节主要介绍如何去设置MediaCapture拍照的分辨率. MediaCapture 包含一个 VideoDeviceController对象,凭借它可以控制摄像头的很多设置,其中包括设置拍照的分 ...
- How To Scan QRCode For UWP (2)
这篇随笔主要介绍照相预览功能,重要使用的是MediaCapture对象,MediaCapture对象还可以用来处理录音和录制视频,本文只讨论照相功能. 1:查找摄像头 后置摄像头优先,找不到后置摄像头 ...
- 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里 ...
随机推荐
- string流
istringstream和ostringstream 从istringstream类中读取数据赋值给某个string,写入某个string到ostringstream类,头文件<sstream ...
- C++之基于排序方法求一组数的中位数
中位数也就是中值: 故需要先对数组进行排序(选择,插入,冒泡排序),然后在找出数组的中值. //求中值 #include<iostream> using namespace std; in ...
- ssh 认证
ssh 秘钥认证流程 ssh配置认证 基于口令(密码)的安全验证 [root@m01 ~]# ssh 10.0.0.41 hostname root@10.0.0.41's password: bac ...
- 学以致用十-----centos7.2+python3.6+vim8.1+YouCompleteMe
趟过了之前的坑后,再来安装YouCompleteMe 一.安装依赖包 yum install libXt-devel gtk2-devel yum -y install python-devel ru ...
- c3p0使用
c3p0-config.xml <?xml version="1.0" encoding="UTF-8"?> <c3p0-config> ...
- 关于TM影像各波段组合的简介
321:真彩色合成,即3.2.1波段分别赋予红.绿.蓝色,则获得自然彩色合成图像,图像的色彩与原地区或景物的实际色彩一致,适合于非遥感应用专业人员使用. 432:标准假彩色合成,即4.3.2波段分别赋 ...
- POJ3280--Cheapest Palindrome(动态规划)
Keeping track of all the cows can be a tricky task so Farmer John has installed a system to automate ...
- 【Andorid开发框架学习】之Mina开发之Mina简介
今天我将介绍 Apache MINA的基本概念和 API,包括 I/O服务.I/O 会话.I/O 过滤器和 I/O 处理器. 一.MINA的简介 Apache MINA是一个网络应用程序框架,用来帮助 ...
- jenkins+maven+svn构建项目,及远程部署war包到tomcat上
要使用jenkins构建项目,当然要使用jenkins了,我使用的war版本的jenkins jenkins的官网 http://jenkins-ci.org/ 点击latest下载,但是可能因为天朝 ...
- 第82讲:Scala中List的ListBuffer是如何实现高效的遍历计算的?
今天学习下list中的ListBuffer实现的高效计算.让我们先来看下代码 def main(args:Array[String]){ val list = List(1,2,3,4, ...