QQ登录

只需一步,快速开始

新浪微博登陆

只需一步, 快速开始

切换风格 注册 找回密码

wp开发-WP教程网


总共224条微博

动态微博

277

主题

2

听众

1828

积分

研究生

Rank: 9Rank: 9Rank: 9

升级   100%

该用户从未签到

积分
1828
金钱
202
威望
120

社区QQ达人 突出贡献 优秀版主 荣誉管理 论坛元老 宣传达人

发表于 2014-10-30 16:38 |显示全部楼层
随着 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.添加页面代码
  1. <Grid x:Name="LayoutRoot"  Background="Black">
  2.         <Grid Background="Black">
  3.             <Grid.ColumnDefinitions>
  4.                 <ColumnDefinition Width="50"/>
  5.                 <ColumnDefinition Width="300"/>
  6.                 <ColumnDefinition Width="50"/>
  7.             </Grid.ColumnDefinitions>
  8.             <Grid Grid.Column="0" Height="366" Margin="0,0,0,0">

  9.             </Grid>
  10.             <!--取景器区域-->
  11.             <Grid Grid.Column="1" x:Name="ScanViewGrid" Margin="0,0,0,0">
  12.                 <Grid.Resources>
  13.                     <Storyboard x:Name="myStoryboard">
  14.                         <DoubleAnimation
  15.                                     Storyboard.TargetName="imgScan"
  16.                                     Storyboard.TargetProperty="(Canvas.Top)"
  17.                                     Duration="0:0:2.5"
  18.                                     From="0"
  19.                                     To="300"
  20.                                     RepeatBehavior="Forever"/>
  21.                     </Storyboard>
  22.                 </Grid.Resources>
  23.                 <!--扫描线-->
  24.                
  25.                     <Canvas Width="300"  Canvas.Top="170"  Height="300">
  26.                         <CaptureElement  Stretch="UniformToFill" x:Name="VideoCapture"  Width="300" Height="300"  >
  27.                         
  28.                         </CaptureElement>
  29.                         <Image x:Name="imgScan" Source="/Assets/img/light.png"  Width="300" Height="40" Stretch="Fill"/>

  30.                         <Image x:Name="CaptureImage" Width="300" Height="300"  Visibility="Collapsed" />
  31.                     </Canvas>
  32.               
  33.          
  34.             </Grid>
  35.             <Grid Grid.Column="2" Margin="0,0,0,0"/>
  36.         </Grid>
  37.       
  38.         <TextBlock x:Name="Error" VerticalAlignment="Bottom" FontSize="32" Width="400" TextAlignment="Center" />
  39.         <TextBlock x:Name="ScanResult" Text="hhh" FontSize="25" Foreground="White" VerticalAlignment="Bottom" TextAlignment="Center" Width="400"/>
  40.     </Grid>
复制代码
3.功能实现
  1. public sealed partial class QCodeView : Page
  2.     {
  3.         private readonly MediaCapture _mediaCapture = new MediaCapture();
  4.         private Result _result;
  5.         private NavigationHelper navigationHelper;
  6.         private ObservableDictionary defaultViewModel = new ObservableDictionary();
  7.         private DispatcherTimer _timer;
  8.       
  9.         public QCodeView()
  10.         {
  11.             this.InitializeComponent();
  12.             //设备屏幕方向
  13.             DisplayInformation.AutoRotationPreferences = DisplayOrientations.Portrait;
  14.             ///隐藏StatusBar
  15.             var statusBar = StatusBar.GetForCurrentView();
  16.             statusBar.HideAsync();
  17.             this.navigationHelper = new NavigationHelper(this);
  18.             this.navigationHelper.LoadState += this.NavigationHelper_LoadState;
  19.             this.navigationHelper.SaveState += this.NavigationHelper_SaveState;
  20.         }

  21.         /// <summary>
  22.         /// 获取与此 <see cref="Page"/> 关联的 <see cref="NavigationHelper"/>。
  23.         /// </summary>
  24.         public NavigationHelper NavigationHelper
  25.         {
  26.             get { return this.navigationHelper; }
  27.         }

  28.         /// <summary>
  29.         /// 获取此 <see cref="Page"/> 的视图模型。
  30.         /// 可将其更改为强类型视图模型。
  31.         /// </summary>
  32.         public ObservableDictionary DefaultViewModel
  33.         {
  34.             get { return this.defaultViewModel; }
  35.         }

  36.         /// <summary>
  37.         /// 使用在导航过程中传递的内容填充页。  在从以前的会话
  38.         /// 重新创建页时,也会提供任何已保存状态。
  39.         /// </summary>
  40.         /// <param name="sender">
  41.         /// 事件的来源; 通常为 <see cref="NavigationHelper"/>
  42.         /// </param>
  43.         /// <param name="e">事件数据,其中既提供在最初请求此页时传递给
  44.         /// <see cref="Frame.Navigate(Type, Object)"/> 的导航参数,又提供
  45.         /// 此页在以前会话期间保留的状态的
  46.         /// 字典。 首次访问页面时,该状态将为 null。</param>
  47.         private void NavigationHelper_LoadState(object sender, LoadStateEventArgs e)
  48.         {
  49.         }

  50.         /// <summary>
  51.         /// 保留与此页关联的状态,以防挂起应用程序或
  52.         /// 从导航缓存中放弃此页。值必须符合
  53.         /// <see cref="SuspensionManager.SessionState"/> 的序列化要求。
  54.         /// </summary>
  55.         /// <param name="sender">事件的来源;通常为 <see cref="NavigationHelper"/></param>
  56.         ///<param name="e">提供要使用可序列化状态填充的空字典
  57.         ///的事件数据。</param>
  58.         private void NavigationHelper_SaveState(object sender, SaveStateEventArgs e)
  59.         {

  60.         }

  61.         #region NavigationHelper 注册

  62.         /// <summary>
  63.         /// 此部分中提供的方法只是用于使
  64.         /// NavigationHelper 可响应页面的导航方法。
  65.         /// <para>
  66.         /// 应将页面特有的逻辑放入用于
  67.         /// <see cref="NavigationHelper.LoadState"/>
  68.         /// 和 <see cref="NavigationHelper.SaveState"/> 的事件处理程序中。
  69.         /// 除了在会话期间保留的页面状态之外
  70.         /// LoadState 方法中还提供导航参数。
  71.         /// </para>
  72.         /// </summary>
  73.         /// <param name="e">提供导航方法数据和
  74.         /// 无法取消导航请求的事件处理程序。</param>
  75.         protected  override void OnNavigatedTo(NavigationEventArgs e)
  76.         {
  77.          
  78.             myStoryboard.Begin();
  79.             InitVideoCapture();
  80.             InitVideoTimer();
  81.                
  82.             this.navigationHelper.OnNavigatedTo(e);
  83.         }


  84.         /// <summary>
  85.         /// 初始化摄像
  86.         /// </summary>
  87.         private async void InitVideoCapture()
  88.         {
  89.             ///摄像头的检测
  90.             var cameras = await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture);
  91.             if (cameras.Count < 1)
  92.             {
  93.                 Error.Text = "设备没有摄像头,读取本地资源";
  94.                 await DecodeStaticResource();
  95.                 return;
  96.             }
  97.            
  98.             ///  创建 MediaCaptureInitializationSettings 对象的新实例。
  99.             var settings = new MediaCaptureInitializationSettings
  100.             {
  101.                 StreamingCaptureMode = StreamingCaptureMode.AudioAndVideo,
  102.                 MediaCategory = MediaCategory.Other,
  103.                 AudioProcessing = Windows.Media.AudioProcessing.Default,
  104.                 VideoDeviceId = cameras[1].Id
  105.             };
  106.             //if (cameras.Count == 1)
  107.             //{
  108.             //    settings = new MediaCaptureInitializationSettings { VideoDeviceId = cameras[0].Id }; // 0 => front, 1 => back
  109.             //}
  110.             //else
  111.             //{
  112.             //    settings = new MediaCaptureInitializationSettings { VideoDeviceId = cameras[1].Id }; // 0 => front, 1 => back
  113.             //}

  114.             await _mediaCapture.InitializeAsync(settings);
  115.             VideoCapture.Source = _mediaCapture;
  116.             await _mediaCapture.StartPreviewAsync();
  117.         }
  118.         private void InitVideoTimer()
  119.         {
  120.             _timer = new DispatcherTimer();
  121.             _timer.Interval = TimeSpan.FromSeconds(6);
  122.             _timer.Tick += _timer_Tick;
  123.             _timer.Start();

  124.         }
  125.         private bool IsBusy = false;
  126.         async void _timer_Tick(object sender, object e)
  127.         {
  128.             try
  129.             {
  130.                 while (_result == null)
  131.                 {
  132.                     if (!IsBusy)
  133.                     {
  134.                         IsBusy = true;
  135.                         ///获取焦点
  136.                         //var autoFocusSupported = _mediaCapture.VideoDeviceController.FocusControl.SupportedFocusModes.Contains(FocusMode.Auto);
  137.                         //if (autoFocusSupported)
  138.                         //{
  139.                         //    var focusSettings = new FocusSettings
  140.                         //    {
  141.                         //        Mode = FocusMode.Auto,
  142.                         //        AutoFocusRange = AutoFocusRange.Normal
  143.                         //    };
  144.                         //    _mediaCapture.VideoDeviceController.FocusControl.Configure(focusSettings);
  145.                         //    //await _mediaCapture.VideoDeviceController.FocusControl.FocusAsync().AsTask(_cancellationTokenSource.Token);
  146.                         //}

  147.                         var photoStorageFile = await KnownFolders.PicturesLibrary.CreateFileAsync("qcode.jpg", CreationCollisionOption.ReplaceExisting);
  148.                         await _mediaCapture.CapturePhotoToStorageFileAsync(ImageEncodingProperties.CreateJpeg(), photoStorageFile);

  149.                         var stream = await photoStorageFile.OpenReadAsync();
  150.                         // initialize with 1,1 to get the current size of the image
  151.                         var writeableBmp = new WriteableBitmap(1, 1);
  152.                         writeableBmp.SetSource(stream);
  153.                         // and create it again because otherwise the WB isn't fully initialized and decoding
  154.                         // results in a IndexOutOfRange
  155.                         writeableBmp = new WriteableBitmap(writeableBmp.PixelWidth, writeableBmp.PixelHeight);
  156.                         stream.Seek(0);
  157.                         writeableBmp.SetSource(stream);
  158.                         _result = ScanBitmap(writeableBmp);
  159.                         await photoStorageFile.DeleteAsync(StorageDeleteOption.PermanentDelete);
  160.                     }
  161.                     if (_result != null)
  162.                     {
  163.                         await _mediaCapture.StopPreviewAsync();
  164.                         VideoCapture.Visibility = Visibility.Collapsed;
  165.                         CaptureImage.Visibility = Visibility.Visible;
  166.                         ScanResult.Text = _result.Text;
  167.                         _timer.Stop();
  168.                         myStoryboard.Stop();
  169.                         imgScan.Visibility = Visibility.Collapsed;
  170.                        
  171.                     }  
  172.                     IsBusy = false;
  173.                  
  174.                 }
  175.             }
  176.             catch (Exception ex)
  177.             {
  178.                
  179.                 IsBusy = false;
  180.                 //Error.Text = ex.Message;
  181.             }
  182.         }
  183.         /// <summary>
  184.         /// 读取本地资源
  185.         /// </summary>
  186.         /// <returns></returns>
  187.         private async System.Threading.Tasks.Task DecodeStaticResource()
  188.         {
  189.             var file = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(@"Assets\1.png");
  190.             var stream = await file.OpenReadAsync();
  191.             // initialize with 1,1 to get the current size of the image
  192.             var writeableBmp = new WriteableBitmap(1, 1);
  193.             writeableBmp.SetSource(stream);
  194.             // and create it again because otherwise the WB isn't fully initialized and decoding
  195.             // results in a IndexOutOfRange
  196.             writeableBmp = new WriteableBitmap(writeableBmp.PixelWidth, writeableBmp.PixelHeight);
  197.             stream.Seek(0);
  198.             writeableBmp.SetSource(stream);
  199.             CaptureImage.Source = writeableBmp;
  200.             VideoCapture.Visibility = Visibility.Collapsed;
  201.             CaptureImage.Visibility = Visibility.Visible;

  202.             _result = ScanBitmap(writeableBmp);
  203.             if (_result != null)
  204.             {
  205.                 ScanResult.Text += _result.Text;
  206.             }
  207.             return;
  208.         }
  209.         /// <summary>
  210.         /// 解析二维码图片
  211.         /// </summary>
  212.         /// <param name="writeableBmp">拍摄的图片</param>
  213.         /// <returns></returns>
  214.         private Result ScanBitmap(WriteableBitmap writeableBmp)
  215.         {
  216.             var barcodeReader = new BarcodeReader
  217.             {
  218.                 TryHarder = true,
  219.                 AutoRotate = true
  220.             };
  221.             var result = barcodeReader.Decode(writeableBmp);

  222.             if (result != null)
  223.             {
  224.                 CaptureImage.Source = writeableBmp;
  225.             }

  226.             return result;
  227.         }
  228.         /// <summary>
  229.         /// 页面离开时对_mediaCapture对象进行释放
  230.         /// 防止内存溢出及资源占用
  231.         /// </summary>
  232.         /// <param name="e"></param>
  233.         protected override async void OnNavigatedFrom(NavigationEventArgs e)
  234.         {
  235.             try
  236.             {
  237.                 await _mediaCapture.StopPreviewAsync();
  238.                 await _mediaCapture.StopRecordAsync();
  239.                 _mediaCapture.Dispose();
  240.             }
  241.             catch (Exception)
  242.             {

  243.             }
  244.             this.navigationHelper.OnNavigatedFrom(e);
  245.         }
  246.         #endregion
  247.     }
复制代码
  注意事项: 在调试时如果出现死机现象 ,请长按锁屏键+音量(-)键 方可重启手机。
源码下载地址:
游客,如果您要查看本帖隐藏内容请回复

0

主题

0

听众

14

积分

新手上路

Rank: 1

升级   28%

该用户从未签到

积分
14
金钱
0
威望
5

社区QQ达人

发表于 2015-2-11 09:15 |显示全部楼层
原先写安卓的时候,有关二维码的文档很多,现在找wp8.1的资料却很不好找,谢谢楼主的分享
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册 新浪微博登陆



关于我们|Archiver|

wp教程网 Powered by Discuz! X2.5

© 2001-2012 Comsenz Inc.

回顶部