Win10/UWP 扫描二维码
在Win10开发中,扫描二维码以及拍照都和以前的Windows 8.1 相同,是使用MediaCapture对象来获取图片或者视频预览数据,通过MediaCapture的CapturePhotoToStreamAsync()方法就可以拿到IRandomAccessStream流进行二维码解析或者做其他的图片操作,MediaCapture也提供了CapturePhotoToStorageFileAsync()方法来获取到IStorageFile流进行文件的操作。
下面贴下代码展示下Win10中的扫描二维码,就不一一讲解了,和以前的Windows8.1的方法类似,解析二维码用的 zxing.NET 。
前台(需要注意的是用了Behaviors,记得添加 Behaviors SDK 的引用):
- <Page.Resources>
- <Storyboard x:Name="LineStoryboard" AutoReverse="True" RepeatBehavior="Forever">
- <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="recScanning">
- <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
- <EasingDoubleKeyFrame KeyTime="0:0:1.5" Value="-269.94"/>
- </DoubleAnimationUsingKeyFrames>
- </Storyboard>
- </Page.Resources>
- <Interactivity:Interaction.Behaviors>
- <Core:EventTriggerBehavior EventName="Loaded">
- <Media:ControlStoryboardAction Storyboard="{StaticResource LineStoryboard}"/>
- </Core:EventTriggerBehavior>
- </Interactivity:Interaction.Behaviors>
- <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
- <Grid x:Name="LayoutRoot" >
- <Grid x:Name="ContentPanel" >
- <!--视频流预览-->
- <CaptureElement x:Name="VideoCapture"/>
- <!--Tips-->
- <TextBlock x:Name="tbkTip" Foreground="White" VerticalAlignment="Bottom" HorizontalAlignment="Center" Margin="36" Text="提示:请将二维码图案放置在取景框内"/>
- <Grid Width="306" Height="306">
- <Rectangle Width="3" Height="50" Fill="Red" HorizontalAlignment="Left" VerticalAlignment="Top"/>
- <Rectangle Width="3" Height="50" Fill="Red" HorizontalAlignment="Right" VerticalAlignment="Top"/>
- <Rectangle Width="3" Height="50" Fill="Red" HorizontalAlignment="Left" VerticalAlignment="Bottom"/>
- <Rectangle Width="3" Height="50" Fill="Red" HorizontalAlignment="Right" VerticalAlignment="Bottom"/>
- <Rectangle Width="50" Height="3" Fill="Red" HorizontalAlignment="Left" VerticalAlignment="Top"/>
- <Rectangle Width="50" Height="3" Fill="Red" HorizontalAlignment="Right" VerticalAlignment="Top"/>
- <Rectangle Width="50" Height="3" Fill="Red" HorizontalAlignment="Left" VerticalAlignment="Bottom"/>
- <Rectangle Width="50" Height="3" Fill="Red" HorizontalAlignment="Right" VerticalAlignment="Bottom"/>
- <Rectangle x:Name="recScanning" Margin="12,0,12,16" Height="2" RenderTransformOrigin="0.5,0.5" VerticalAlignment="Bottom" d:LayoutOverrides="Height">
- <Rectangle.RenderTransform>
- <CompositeTransform/>
- </Rectangle.RenderTransform>
- <Rectangle.Projection>
- <PlaneProjection/>
- </Rectangle.Projection>
- <Rectangle.Fill>
- <LinearGradientBrush EndPoint="0,0.5" StartPoint="1,0.5">
- <GradientStop Color="#331CF106" Offset="0.15"/>
- <GradientStop Color="#331CF106" Offset="0.85"/>
- <GradientStop Color="#FF1CF106" Offset="0.5"/>
- </LinearGradientBrush>
- </Rectangle.Fill>
- </Rectangle>
- </Grid>
- </Grid>
- <!--扫描结果-->
- <TextBlock x:Name="tbkResult" Grid.Row="1" Foreground="White" VerticalAlignment="Top" TextWrapping="Wrap" Margin="12,18" FontSize="25" Text="扫描结果:"/>
- </Grid>
- </Grid>
后台:
- public sealed partial class MainPage : Page
- {
- private Result _result;
- private readonly MediaCapture _mediaCapture = new MediaCapture();
- private DispatcherTimer _timer;
- private bool IsBusy;
- public MainPage()
- {
- this.InitializeComponent();
- }
- protected override void OnNavigatedTo(NavigationEventArgs e)
- {
- base.OnNavigatedTo(e);
- InitVideoCapture();
- InitVideoTimer();
- }
- private void InitVideoTimer()
- {
- _timer = new DispatcherTimer();
- _timer.Interval = TimeSpan.FromSeconds(3);
- _timer.Tick += _timer_Tick;
- _timer.Start();
- }
- private async void _timer_Tick(object sender, object e)
- {
- try
- {
- Debug.WriteLine(@"[INFO]开始扫描 -> " + DateTime.Now.ToString());
- if (!IsBusy)
- {
- IsBusy = true;
- IRandomAccessStream stream = new InMemoryRandomAccessStream();
- await _mediaCapture.CapturePhotoToStreamAsync(ImageEncodingProperties.CreateJpeg(), stream);
- var writeableBmp = await ReadBitmap(stream, ".jpg");
- await Task.Factory.StartNew(async () => { await ScanBitmap(writeableBmp); });
- }
- IsBusy = false;
- await Task.Delay(50);
- }
- catch (Exception)
- {
- IsBusy = false;
- }
- }
- /// <summary>
- /// 保存照片
- /// </summary>
- /// <param name="stream"></param>
- /// <param name="fileName"></param>
- /// <param name="photoOrientation"></param>
- /// <returns></returns>
- private static async Task ReencodeAndSavePhotoAsync(IRandomAccessStream stream, string fileName, PhotoOrientation photoOrientation = PhotoOrientation.Normal)
- {
- using (var inputStream = stream)
- {
- var decoder = await BitmapDecoder.CreateAsync(inputStream);
- var file = await KnownFolders.PicturesLibrary.CreateFileAsync(fileName, CreationCollisionOption.GenerateUniqueName);
- using (var outputStream = await file.OpenAsync(FileAccessMode.ReadWrite))
- {
- var encoder = await BitmapEncoder.CreateForTranscodingAsync(outputStream, decoder);
- // Set the orientation of the capture
- var properties = new BitmapPropertySet { { "System.Photo.Orientation", new BitmapTypedValue(photoOrientation, PropertyType.UInt16) } };
- await encoder.BitmapProperties.SetPropertiesAsync(properties);
- await encoder.FlushAsync();
- }
- }
- }
- static Guid DecoderIDFromFileExtension(string strExtension)
- {
- Guid encoderId;
- switch (strExtension.ToLower())
- {
- case ".jpg":
- case ".jpeg":
- encoderId = BitmapDecoder.JpegDecoderId;
- break;
- case ".bmp":
- encoderId = BitmapDecoder.BmpDecoderId;
- break;
- case ".png":
- default:
- encoderId = BitmapDecoder.PngDecoderId;
- break;
- }
- return encoderId;
- }
- public static Size MaxSizeSupported = new Size(4000, 3000);
- /// <summary>
- /// 读取照片流 转为WriteableBitmap给二维码解码器
- /// </summary>
- /// <param name="fileStream"></param>
- /// <param name="type"></param>
- /// <returns></returns>
- public async static Task<WriteableBitmap> ReadBitmap(IRandomAccessStream fileStream, string type)
- {
- WriteableBitmap bitmap = null;
- try
- {
- Guid decoderId = DecoderIDFromFileExtension(type);
- BitmapDecoder decoder = await BitmapDecoder.CreateAsync(decoderId, fileStream);
- BitmapTransform tf = new BitmapTransform();
- uint width = decoder.OrientedPixelWidth;
- uint height = decoder.OrientedPixelHeight;
- double dScale = 1;
- if (decoder.OrientedPixelWidth > MaxSizeSupported.Width || decoder.OrientedPixelHeight > MaxSizeSupported.Height)
- {
- dScale = Math.Min(MaxSizeSupported.Width / decoder.OrientedPixelWidth, MaxSizeSupported.Height / decoder.OrientedPixelHeight);
- width = (uint)(decoder.OrientedPixelWidth * dScale);
- height = (uint)(decoder.OrientedPixelHeight * dScale);
- tf.ScaledWidth = (uint)(decoder.PixelWidth * dScale);
- tf.ScaledHeight = (uint)(decoder.PixelHeight * dScale);
- }
- bitmap = new WriteableBitmap((int)width, (int)height);
- PixelDataProvider dataprovider = await decoder.GetPixelDataAsync(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, tf,
- ExifOrientationMode.RespectExifOrientation, ColorManagementMode.DoNotColorManage);
- byte[] pixels = dataprovider.DetachPixelData();
- Stream pixelStream2 = bitmap.PixelBuffer.AsStream();
- pixelStream2.Write(pixels, 0, pixels.Length);
- //bitmap.SetSource(fileStream);
- }
- catch
- {
- }
- return bitmap;
- }
- /// <summary>
- /// 解析二维码图片
- /// </summary>
- /// <param name="writeableBmp">图片</param>
- /// <returns></returns>
- private async Task ScanBitmap(WriteableBitmap writeableBmp)
- {
- try
- {
- var barcodeReader = new BarcodeReader
- {
- AutoRotate = true,
- Options = new ZXing.Common.DecodingOptions { TryHarder = true }
- };
- await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
- {
- _result = barcodeReader.Decode(writeableBmp);
- });
- if (_result != null)
- {
- Debug.WriteLine(@"[INFO]扫描到二维码:{result} ->" + _result.Text);
- await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
- {
- tbkResult.Text = _result.Text;
- });
- }
- }
- catch (Exception)
- {
- }
- }
- private async void InitVideoCapture()
- {
- ///摄像头的检测
- var cameraDevice = await FindCameraDeviceByPanelAsync(Windows.Devices.Enumeration.Panel.Back);
- if (cameraDevice == null)
- {
- Debug.WriteLine("No camera device found!");
- return;
- }
- var settings = new MediaCaptureInitializationSettings
- {
- StreamingCaptureMode = StreamingCaptureMode.Video,
- MediaCategory = MediaCategory.Other,
- AudioProcessing = Windows.Media.AudioProcessing.Default,
- VideoDeviceId = cameraDevice.Id
- };
- await _mediaCapture.InitializeAsync(settings);
- VideoCapture.Source = _mediaCapture;
- await _mediaCapture.StartPreviewAsync();
- }
- 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();
- }
- }
效果:

本文出自:53078485群大咖Aran

浙公网安备 33010602011771号