WindowsPhone8.1 开发-- 二维码扫描
随着 WinRT 8.1 API 的发布,Windows 8.1 和 Windows Phone 8.1 (基于 WinRT) 应用程序的开发模型经历了戏剧性的收敛性。与一些特定于平台的考虑,我们现在可以为 Windows 和使用几乎相同的 XAML 框架和 API 来开发 Windows Phone 开发应用程序。
"旧的"基于 Windows Phone 8.0 Silverlight API 将继续得到支持和改善,但基于 WinRT 的融合的模型显然是要在未来走的路。
所以抽时间实现了wp8.1实现二维码扫描的功能
1. 在项目中添加对Zxing的引用
Zxing示例代码下载地址:http://zxingnet.codeplex.com/
2.添加页面代码
<Grid x:Name="LayoutRoot" Background="Black">
<Grid Background="Black">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="300"/>
<ColumnDefinition Width="50"/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0" Height="366" Margin="0,0,0,0"> </Grid>
<!--取景器区域-->
<Grid Grid.Column="1" x:Name="ScanViewGrid" Margin="0,0,0,0">
<Grid.Resources>
<Storyboard x:Name="myStoryboard">
<DoubleAnimation
Storyboard.TargetName="imgScan"
Storyboard.TargetProperty="(Canvas.Top)"
Duration="0:0:2.5"
From="0"
To="300"
RepeatBehavior="Forever"/>
</Storyboard>
</Grid.Resources>
<!--扫描线--> <Canvas Width="300" Canvas.Top="170" Height="300">
<CaptureElement Stretch="UniformToFill" x:Name="VideoCapture" Width="300" Height="300" > </CaptureElement>
<Image x:Name="imgScan" Source="/Assets/img/light.png" Width="300" Height="40" Stretch="Fill"/> <Image x:Name="CaptureImage" Width="300" Height="300" Visibility="Collapsed" />
</Canvas> </Grid>
<Grid Grid.Column="2" Margin="0,0,0,0"/>
</Grid> <TextBlock x:Name="Error" VerticalAlignment="Bottom" FontSize="32" Width="400" TextAlignment="Center" />
<TextBlock x:Name="ScanResult" Text="hhh" FontSize="25" Foreground="White" VerticalAlignment="Bottom" TextAlignment="Center" Width="400"/>
</Grid>
3.功能实现
public sealed partial class QCodeView : Page
{
private readonly MediaCapture _mediaCapture = new MediaCapture();
private Result _result;
private NavigationHelper navigationHelper;
private ObservableDictionary defaultViewModel = new ObservableDictionary();
private DispatcherTimer _timer; public QCodeView()
{
this.InitializeComponent();
//设备屏幕方向
DisplayInformation.AutoRotationPreferences = DisplayOrientations.Portrait;
///隐藏StatusBar
var statusBar = StatusBar.GetForCurrentView();
statusBar.HideAsync();
this.navigationHelper = new NavigationHelper(this);
this.navigationHelper.LoadState += this.NavigationHelper_LoadState;
this.navigationHelper.SaveState += this.NavigationHelper_SaveState;
} /// <summary>
/// 获取与此 <see cref="Page"/> 关联的 <see cref="NavigationHelper"/>。
/// </summary>
public NavigationHelper NavigationHelper
{
get { return this.navigationHelper; }
} /// <summary>
/// 获取此 <see cref="Page"/> 的视图模型。
/// 可将其更改为强类型视图模型。
/// </summary>
public ObservableDictionary DefaultViewModel
{
get { return this.defaultViewModel; }
} /// <summary>
/// 使用在导航过程中传递的内容填充页。 在从以前的会话
/// 重新创建页时,也会提供任何已保存状态。
/// </summary>
/// <param name="sender">
/// 事件的来源; 通常为 <see cref="NavigationHelper"/>
/// </param>
/// <param name="e">事件数据,其中既提供在最初请求此页时传递给
/// <see cref="Frame.Navigate(Type, Object)"/> 的导航参数,又提供
/// 此页在以前会话期间保留的状态的
/// 字典。 首次访问页面时,该状态将为 null。</param>
private void NavigationHelper_LoadState(object sender, LoadStateEventArgs e)
{
} /// <summary>
/// 保留与此页关联的状态,以防挂起应用程序或
/// 从导航缓存中放弃此页。值必须符合
/// <see cref="SuspensionManager.SessionState"/> 的序列化要求。
/// </summary>
/// <param name="sender">事件的来源;通常为 <see cref="NavigationHelper"/></param>
///<param name="e">提供要使用可序列化状态填充的空字典
///的事件数据。</param>
private void NavigationHelper_SaveState(object sender, SaveStateEventArgs e)
{ } #region NavigationHelper 注册 /// <summary>
/// 此部分中提供的方法只是用于使
/// NavigationHelper 可响应页面的导航方法。
/// <para>
/// 应将页面特有的逻辑放入用于
/// <see cref="NavigationHelper.LoadState"/>
/// 和 <see cref="NavigationHelper.SaveState"/> 的事件处理程序中。
/// 除了在会话期间保留的页面状态之外
/// LoadState 方法中还提供导航参数。
/// </para>
/// </summary>
/// <param name="e">提供导航方法数据和
/// 无法取消导航请求的事件处理程序。</param>
protected override void OnNavigatedTo(NavigationEventArgs e)
{ myStoryboard.Begin();
InitVideoCapture();
InitVideoTimer(); this.navigationHelper.OnNavigatedTo(e);
} /// <summary>
/// 初始化摄像
/// </summary>
private async void InitVideoCapture()
{
///摄像头的检测
var cameras = await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture);
if (cameras.Count < 1)
{
Error.Text = "设备没有摄像头,读取本地资源";
await DecodeStaticResource();
return;
} /// 创建 MediaCaptureInitializationSettings 对象的新实例。
var settings = new MediaCaptureInitializationSettings
{
StreamingCaptureMode = StreamingCaptureMode.AudioAndVideo,
MediaCategory = MediaCategory.Other,
AudioProcessing = Windows.Media.AudioProcessing.Default,
VideoDeviceId = cameras[1].Id
};
//if (cameras.Count == 1)
//{
// settings = new MediaCaptureInitializationSettings { VideoDeviceId = cameras[0].Id }; // 0 => front, 1 => back
//}
//else
//{
// settings = new MediaCaptureInitializationSettings { VideoDeviceId = cameras[1].Id }; // 0 => front, 1 => back
//} await _mediaCapture.InitializeAsync(settings);
VideoCapture.Source = _mediaCapture;
await _mediaCapture.StartPreviewAsync();
}
private void InitVideoTimer()
{
_timer = new DispatcherTimer();
_timer.Interval = TimeSpan.FromSeconds(6);
_timer.Tick += _timer_Tick;
_timer.Start(); }
private bool IsBusy = false;
async void _timer_Tick(object sender, object e)
{
try
{
while (_result == null)
{
if (!IsBusy)
{
IsBusy = true;
///获取焦点
//var autoFocusSupported = _mediaCapture.VideoDeviceController.FocusControl.SupportedFocusModes.Contains(FocusMode.Auto);
//if (autoFocusSupported)
//{
// var focusSettings = new FocusSettings
// {
// Mode = FocusMode.Auto,
// AutoFocusRange = AutoFocusRange.Normal
// };
// _mediaCapture.VideoDeviceController.FocusControl.Configure(focusSettings);
// //await _mediaCapture.VideoDeviceController.FocusControl.FocusAsync().AsTask(_cancellationTokenSource.Token);
//} var photoStorageFile = await KnownFolders.PicturesLibrary.CreateFileAsync("qcode.jpg", CreationCollisionOption.ReplaceExisting);
await _mediaCapture.CapturePhotoToStorageFileAsync(ImageEncodingProperties.CreateJpeg(), photoStorageFile); var stream = await photoStorageFile.OpenReadAsync();
// initialize with 1,1 to get the current size of the image
var writeableBmp = new WriteableBitmap(1, 1);
writeableBmp.SetSource(stream);
// and create it again because otherwise the WB isn't fully initialized and decoding
// results in a IndexOutOfRange
writeableBmp = new WriteableBitmap(writeableBmp.PixelWidth, writeableBmp.PixelHeight);
stream.Seek(0);
writeableBmp.SetSource(stream);
_result = ScanBitmap(writeableBmp);
await photoStorageFile.DeleteAsync(StorageDeleteOption.PermanentDelete);
}
if (_result != null)
{
await _mediaCapture.StopPreviewAsync();
VideoCapture.Visibility = Visibility.Collapsed;
CaptureImage.Visibility = Visibility.Visible;
ScanResult.Text = _result.Text;
_timer.Stop();
myStoryboard.Stop();
imgScan.Visibility = Visibility.Collapsed; }
IsBusy = false; }
}
catch (Exception ex)
{ IsBusy = false;
//Error.Text = ex.Message;
}
}
/// <summary>
/// 读取本地资源
/// </summary>
/// <returns></returns>
private async System.Threading.Tasks.Task DecodeStaticResource()
{
var file = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(@"Assets\1.png");
var stream = await file.OpenReadAsync();
// initialize with 1,1 to get the current size of the image
var writeableBmp = new WriteableBitmap(1, 1);
writeableBmp.SetSource(stream);
// and create it again because otherwise the WB isn't fully initialized and decoding
// results in a IndexOutOfRange
writeableBmp = new WriteableBitmap(writeableBmp.PixelWidth, writeableBmp.PixelHeight);
stream.Seek(0);
writeableBmp.SetSource(stream);
CaptureImage.Source = writeableBmp;
VideoCapture.Visibility = Visibility.Collapsed;
CaptureImage.Visibility = Visibility.Visible; _result = ScanBitmap(writeableBmp);
if (_result != null)
{
ScanResult.Text += _result.Text;
}
return;
}
/// <summary>
/// 解析二维码图片
/// </summary>
/// <param name="writeableBmp">拍摄的图片</param>
/// <returns></returns>
private Result ScanBitmap(WriteableBitmap writeableBmp)
{
var barcodeReader = new BarcodeReader
{
TryHarder = true,
AutoRotate = true
};
var result = barcodeReader.Decode(writeableBmp); if (result != null)
{
CaptureImage.Source = writeableBmp;
} return result;
}
/// <summary>
/// 页面离开时对_mediaCapture对象进行释放
/// 防止内存溢出及资源占用
/// </summary>
/// <param name="e"></param>
protected override async void OnNavigatedFrom(NavigationEventArgs e)
{
try
{
await _mediaCapture.StopPreviewAsync();
await _mediaCapture.StopRecordAsync();
_mediaCapture.Dispose();
}
catch (Exception)
{ }
this.navigationHelper.OnNavigatedFrom(e);
}
#endregion
}
源码下载地址:http://vdisk.weibo.com/s/ztJnMX2jYqaK3
注意事项: 在调试时如果出现死机现象 ,请长按锁屏键+音量(-)键 方可重启手机。
学习交流QQ群:157153754 (入群成员请将您的昵称改为: 城市-昵称 )
WindowsPhone8.1 开发-- 二维码扫描的更多相关文章
- iOS开发-二维码扫描和应用跳转
iOS开发-二维码扫描和应用跳转 序言 前面我们已经调到过怎么制作二维码,在我们能够生成二维码之后,如何对二维码进行扫描呢? 在iOS7之前,大部分应用中使用的二维码扫描是第三方的扫描框架,例如Z ...
- ipad开发:二维码扫描,摄像头旋转角度问题解决办法
之前一直是在手机上开发,用系统原生二维码扫描功能,一点问题都没有,但是在ipad上,用户是横屏操作的,虽然界面旋转了,是横屏的,但是摄像头里显示的依然是竖屏效果,也就是说从摄像头里看到的和人眼看到的内 ...
- H5混合开发二维码扫描以及调用本地摄像头
今天主管给了我个需求,说要用混合开发,用H5调用本地摄像头进行扫描二维码,我之前有做过原生安卓的二维码扫一扫,主要是通过调用zxing插件进行操作的,其中还弄了个闪光灯.但是纯H5的没接触过,心里没底 ...
- Android开发--二维码开发应用(转载!)
android项目开发 二维码扫描 基于android平台的二维码扫描项目,可以查看结果并且链接网址 工具/原料 zxing eclipse 方法/步骤 首先需要用到google提供的zxin ...
- IOS开发小功能2:二维码扫描界面的设计(横线上下移动)
效果图如上,实现的是一个二维码扫描界面. 下面我贴出线条上下移动的代码,至于二维码的代码是用的第三方库. 首先是整体的结构: 注意下面的库文件一个都不能少,否则会报错. TLTiltHighlight ...
- iOS开发之二维码扫描
二维码扫描 01-导入系统库 02 新建继承自UIView的 LHQPreView 2.1导入系统库头文件 #import <AVFoundation/AVFoundation.h> 2. ...
- IOS开发---菜鸟学习之路--(二十)-二维码扫描功能的实现
本章将讲解如何实现二维码扫描的功能 首先在github上下载ZBar SDK地址https://github.com/bmorton/ZBarSDK 然后将如下的相关类库添加进去 AVFoundati ...
- iOS开发技术 - 二维码扫描、生成
QRecLevel:QR_ECLEVEL_H // 二维码容错率,最高为30%(即QR_ECLEVEL_H),即LOGO有大 ...
- [Unity3D]自制UnityForAndroid二维码扫描插件
一周左右终于将二维码生成和扫描功能给实现了,终于能舒缓一口气了,从一开始的疑惑为啥不同的扫码客户端为啥扫出来的效果不同?通用的扫描器扫出来就是一个下载APK,自制的扫描器扫出来是想要的有效信息,然后分 ...
随机推荐
- workerman搭建聊天室
首先,先打开官网手册 http://doc.workerman.net/ 根据手册里安装里的提示,完成环境检测,和安装对应的扩展,并把对应的WorkerMan代码包下载解压至根目录 在根目录下创建 ...
- python-基础入门-6快速入门总结
快速入门 程序输出: 1.print语句,字符串用双引号括起来 _在解释器中表示最后一个表达式的值. print语句 与字符串格式(%)结合使用,能实现字符串替换功能. >>>pri ...
- 一次看完28个关于ES的性能调优技巧,很赞,值得收藏!
因为总是看到很多同学在说Elasticsearch性能不够好.集群不够稳定,询问关于Elasticsearch的调优,但是每次都是一个个点的单独讲,很多时候都是case by case的解答,本文简单 ...
- 如何查看CDR文件是出自哪个版本?
如何才能知道某个cdr文件用哪个版本的CorelDRAW软件打开?网上CorelDRAW软件有很多版本,都不知该下哪个了?这是我听到大家问道最多的问题,这是因为CDR低版本软件打不开高版本文件. 方法 ...
- 吉他指弹入门——贝斯(walking bass)
在每一个乐队中都有一个神秘而低调的乐手,在现场演奏中你甚至感觉不到他的存在,但是他又异常重要.即是鼓手打拍的好伙伴,又是吉他手忘乎所以solo时的警报器.没错,这个人就是贝斯手.要是我们做了什么气跑了 ...
- Logstash使用mongodb插件报错: ArgumentError: wrong number of arguments (given 2, expected 1)
目录 背景 安装插件过程 背景 今天在使用logstash收集日志存储到mongodb的安装过程遇到了个错误,记录下来,错误就是下面这样: 配置文件很简单,由于是测试环境,命令行传入日志输入由ruby ...
- mac下让iterm2记住远程ssh连接
brew安装sshpass brew install http://git.io/sshpass.rb 在根目录下建立passowrd目录用来管理密码,vim testserver 输入明文密码,保存 ...
- 【ACwing 95】费解的开关——枚举 + 搜索
(题面来自ACwing) 你玩过"拉灯"游戏吗?25盏灯排成一个5x5的方形.每一个灯都有一个开关,游戏者可以改变它的状态.每一步,游戏者可以改变某一个灯的状态.游戏者改变一个灯的 ...
- AA:白细胞计数
总时间限制: 1000ms 内存限制: 65536kB 描述 医院采样了某临床病例治疗期间的白细胞数量样本n份,用于分析某种新抗生素对该病例的治疗效果.为了降低分析误差,要先从这n份样本中去除一个 ...
- 重做系统后 恢复oracle 实例
第一次进行操作,按照网上方法,试了一遍,很多细节搞不清楚,但是还是要记录一下. 备份 old数据库 所用到文件有: XXXXXX\product\11.2.0\dbhome_1\database\pw ...