zoukankan      html  css  js  c++  java
  • Win10 UWP开发:摄像头扫描二维码/一维码功能

    这个示例演示整合了Aran和微软的示例,无需修改即可运行。

    支持识别,二维码/一维码,需要在包清单管理器勾选摄像头权限。

    首先右键项目引用,打开Nuget包管理器搜索安装:ZXing.Net.Mobile

    BarcodePage.xmal页面代码

    <Page
        x:Class="SuperTools.Views.BarcodePage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:SuperTools.Views"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
        <Page.Transitions>
            <TransitionCollection>
                <NavigationThemeTransition>
                    <SlideNavigationTransitionInfo />
                </NavigationThemeTransition>
            </TransitionCollection>
        </Page.Transitions>
    
        <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
            <Grid x:Name="LayoutRoot" >
                <Grid x:Name="ContentPanel" >
                    <!--视频流预览-->
                    <CaptureElement x:Name="VideoCapture" Stretch="UniformToFill"/>
    
                    <Grid Width="300" Height="300" x:Name="ViewGrid">
                        <Rectangle Width="3" Height="50" Fill="Orange" HorizontalAlignment="Left" VerticalAlignment="Top"/>
                        <Rectangle Width="3" Height="50" Fill="Orange" HorizontalAlignment="Right" VerticalAlignment="Top"/>
                        <Rectangle Width="3" Height="50" Fill="Orange" HorizontalAlignment="Left" VerticalAlignment="Bottom"/>
                        <Rectangle Width="3" Height="50" Fill="Orange" HorizontalAlignment="Right" VerticalAlignment="Bottom"/>
                        <Rectangle Width="50" Height="3" Fill="Orange" HorizontalAlignment="Left" VerticalAlignment="Top"/>
                        <Rectangle Width="50" Height="3" Fill="Orange" HorizontalAlignment="Right" VerticalAlignment="Top"/>
                        <Rectangle Width="50" Height="3" Fill="Orange" HorizontalAlignment="Left" VerticalAlignment="Bottom"/>
                        <Rectangle Width="50" Height="3" Fill="Orange" HorizontalAlignment="Right" VerticalAlignment="Bottom"/>
    
                        <Rectangle x:Name="recScanning"  Margin="12,0,12,0" VerticalAlignment="Center" Height="2" Fill="Green" RenderTransformOrigin="0.5,0.5" />
                    </Grid>
                </Grid>
            </Grid>
        </Grid>
    </Page>

    BarcodePage.xmal.cs后台代码

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Runtime.InteropServices.WindowsRuntime;
    using System.Threading.Tasks;
    using Windows.ApplicationModel;
    using Windows.Devices.Enumeration;
    using Windows.Foundation;
    using Windows.Foundation.Collections;
    using Windows.Graphics.Display;
    using Windows.Graphics.Imaging;
    using Windows.Media;
    using Windows.Media.Capture;
    using Windows.Media.Devices;
    using Windows.Media.MediaProperties;
    using Windows.Storage;
    using Windows.Storage.FileProperties;
    using Windows.Storage.Streams;
    using Windows.UI.Core;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Controls.Primitives;
    using Windows.UI.Xaml.Data;
    using Windows.UI.Xaml.Input;
    using Windows.UI.Xaml.Media;
    using Windows.UI.Xaml.Media.Imaging;
    using Windows.UI.Xaml.Navigation;
    using ZXing;
    
    // https://go.microsoft.com/fwlink/?LinkId=234238 上介绍了“空白页”项模板
    
    namespace SuperTools.Views
    {
        /// <summary>
        /// 可用于自身或导航至 Frame 内部的空白页。
        /// </summary>
        public sealed partial class BarcodePage : Page
        {
            private Result _result;
            private MediaCapture _mediaCapture;
            private DispatcherTimer _timer;
            private bool IsBusy;
            private bool _isPreviewing = false;
            private bool _isInitVideo = false;
            BarcodeReader barcodeReader;
    
            private static readonly Guid RotationKey = new Guid("C380465D-2271-428C-9B83-ECEA3B4A85C1");
    
            public BarcodePage()
            {
                barcodeReader = new BarcodeReader
                {
                    AutoRotate = true,
                    Options = new ZXing.Common.DecodingOptions { TryHarder = true }
                };
                this.InitializeComponent();
                this.NavigationCacheMode = NavigationCacheMode.Required;
                Application.Current.Suspending += Application_Suspending;
                Application.Current.Resuming += Application_Resuming;
            }
    
            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();
                }
            }
    
            private void Application_Resuming(object sender, object o)
            {
                // Handle global application events only if this page is active
                if (Frame.CurrentSourcePageType == typeof(MainPage))
                {
                    InitVideoCapture();
                }
            }
    
            protected override async void OnNavigatingFrom(NavigatingCancelEventArgs e)
            {
                // Handling of this event is included for completenes, as it will only fire when navigating between pages and this sample only includes one page
                await CleanupCameraAsync();
            }
    
            protected override void OnNavigatedTo(NavigationEventArgs e)
            {
                base.OnNavigatedTo(e);
                InitVideoCapture();
            }
    
            private async Task CleanupCameraAsync()
            {
                if (_isPreviewing)
                {
                    await StopPreviewAsync();
                }
                _timer.Stop();
                if (_mediaCapture != null)
                {
                    _mediaCapture.Dispose();
                    _mediaCapture = null;
                }
            }
    
            private void InitVideoTimer()
            {
                _timer = new DispatcherTimer();
                _timer.Interval = TimeSpan.FromSeconds(1);
                _timer.Tick += _timer_Tick;
                _timer.Start();
            }
    
            private async Task StopPreviewAsync()
            {
                _isPreviewing = false;
                await _mediaCapture.StopPreviewAsync();
    
                // Use the dispatcher because this method is sometimes called from non-UI threads
                await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                {
                    VideoCapture.Source = null;
                });
            }
    
            private async void _timer_Tick(object sender, object e)
            {
                try
                {
                    if (!IsBusy)
                    {
                        IsBusy = true;
    
                        var previewProperties = _mediaCapture.VideoDeviceController.GetMediaStreamProperties(MediaStreamType.VideoPreview) as VideoEncodingProperties;
    
                        VideoFrame videoFrame = new VideoFrame(BitmapPixelFormat.Bgra8, (int)previewProperties.Width, (int)previewProperties.Height);
                        VideoFrame previewFrame = await _mediaCapture.GetPreviewFrameAsync(videoFrame);
    
                        WriteableBitmap bitmap = new WriteableBitmap(previewFrame.SoftwareBitmap.PixelWidth, previewFrame.SoftwareBitmap.PixelHeight);
    
                        previewFrame.SoftwareBitmap.CopyToBuffer(bitmap.PixelBuffer);
    
                        await Task.Factory.StartNew(async () => { await ScanBitmap(bitmap); });
                    }
                    IsBusy = false;
                    await Task.Delay(50);
                }
                catch (Exception)
                {
                    IsBusy = false;
                }
            }
    
            /// <summary>
            /// 解析二维码图片
            /// </summary>
            /// <param name="writeableBmp">图片</param>
            /// <returns></returns>
            private async Task ScanBitmap(WriteableBitmap writeableBmp)
            {
                try
                {
                    await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                    {
                        _result = barcodeReader.Decode(writeableBmp.PixelBuffer.ToArray(), writeableBmp.PixelWidth, writeableBmp.PixelHeight, RGBLuminanceSource.BitmapFormat.Unknown);
                        if (_result != null)
                        {
                            //TODO: 扫描结果:_result.Text
                        }
                    });
    
                }
                catch (Exception)
                {
                }
            }
    
            private async void InitVideoCapture()
            {
                ///摄像头的检测  
                var cameraDevice = await FindCameraDeviceByPanelAsync(Windows.Devices.Enumeration.Panel.Back);
    
                if (cameraDevice == null)
                {
                    System.Diagnostics.Debug.WriteLine("No camera device found!");
                    return;
                }
                var settings = new MediaCaptureInitializationSettings
                {
                    StreamingCaptureMode = StreamingCaptureMode.Video,
                    MediaCategory = MediaCategory.Other,
                    AudioProcessing = AudioProcessing.Default,
                    VideoDeviceId = cameraDevice.Id
                };
                _mediaCapture = new MediaCapture();
                await _mediaCapture.InitializeAsync(settings);
    
                VideoCapture.Source = _mediaCapture;
                await _mediaCapture.StartPreviewAsync();
    
                var props = _mediaCapture.VideoDeviceController.GetMediaStreamProperties(MediaStreamType.VideoPreview);
                props.Properties.Add(RotationKey, 90);
    
                await _mediaCapture.SetEncodingPropertiesAsync(MediaStreamType.VideoPreview, props, null);
    
                var focusControl = _mediaCapture.VideoDeviceController.FocusControl;
    
                if (focusControl.Supported)
                {
                    await focusControl.UnlockAsync();
                    var setting = new FocusSettings { Mode = FocusMode.Continuous, AutoFocusRange = AutoFocusRange.FullRange };
                    focusControl.Configure(setting);
                    await focusControl.FocusAsync();
                }
    
                _isPreviewing = true;
                _isInitVideo = true;
                InitVideoTimer();
            }
    
            private static async Task<DeviceInformation> FindCameraDeviceByPanelAsync(Windows.Devices.Enumeration.Panel desiredPanel)
            {
                var allVideoDevices = await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture);
    
                DeviceInformation desiredDevice = allVideoDevices.FirstOrDefault(x => x.EnclosureLocation != null && x.EnclosureLocation.Panel == desiredPanel);
    
                return desiredDevice ?? allVideoDevices.FirstOrDefault();
            }
        }
    }
  • 相关阅读:
    效果超酷的textarea的输入字数限提示
    【设计模式(七)】结构型模式之桥接模式
    【设计模式(六)】适配器模式
    【设计模式(四)】原型模式
    【设计模式(三)】工厂模式
    【设计模式(二)】单例模式
    【设计模式(一)】设计模式概览与六大设计原则
    【算法刷题】无重复字符的最长子串
    【算法刷题】全排列 II
    【算法刷题】LRU缓存模拟
  • 原文地址:https://www.cnblogs.com/myhalo/p/6635325.html
Copyright © 2011-2022 走看看