zoukankan      html  css  js  c++  java
  • How To Scan QRCode For UWP (3)

    这一节主要介绍如何去设置MediaCapture拍照的分辨率。

    MediaCapture 包含一个 VideoDeviceController对象,凭借它可以控制摄像头的很多设置,其中包括设置拍照的分辨率。 首先通过GetAvailableMediaStreamProperties方法来获取设备所支持的 Encoding Properties,要注意的是即使你指定了MediaStreamType为Photo,这个API也会有可能同时返回 ImageEncodingProperties /VideoEncodingProperties对象。 因此我们在比较设备支持的Encoding Properties,需要手动去将它强制转换为 ImageEncodingProperties/VideoEncodingProperties对象。 此外还需要找到宽高比非常接近我们所期望的分辨率,误差范围在0.015之内。示例代码使用的宽高比为16:9,常见的还有4:3。

    比较奇怪的IMediaEncodingProperties没有声明Width/Height属性,让代码写的有点啰嗦。

     实现代码如下:

     1  uint desiredWidth = 1920;
     2         uint desiredHeight = 1080;
     3 
     4         private async Task<uint[]> SetResolution(MediaStreamType streamType)
     5         {
     6             //Get the supported encoding properties. 
     7             var mediaStreamProperties = mediaCapture.VideoDeviceController.GetAvailableMediaStreamProperties(streamType);
     8             if (mediaStreamProperties == null || mediaStreamProperties.Count == 0)
     9                 return null;
    10 
    11             var imageEncodingProperty = mediaStreamProperties.Select(e => e as ImageEncodingProperties)
    12                                                              .Where(e => e != null && e.Width <= desiredWidth
    13                                                                         && e.Height < desiredHeight && IsMatchingRatio(e))
    14                                                              .OrderByDescending(e => e.Width * e.Height)
    15                                                              .FirstOrDefault();
    16             if (imageEncodingProperty != null)
    17             {
    18                 await mediaCapture.VideoDeviceController.SetMediaStreamPropertiesAsync(streamType, imageEncodingProperty);
    19                 return new uint[] { imageEncodingProperty.Width, imageEncodingProperty.Height };
    20             }
    21 
    22             var videoEncodingProperty = mediaStreamProperties.Select(e => e as VideoEncodingProperties)
    23                                                            .Where(e => e != null && e.Width <= desiredWidth
    24                                                                       && e.Height < desiredHeight && IsMatchingRatio(e))
    25                                                            .OrderByDescending(e => e.Width * e.Height)
    26                                                            .FirstOrDefault();
    27             if (videoEncodingProperty != null)
    28             {
    29                 await mediaCapture.VideoDeviceController.SetMediaStreamPropertiesAsync(streamType, videoEncodingProperty);
    30                 return new uint[] { videoEncodingProperty.Width, videoEncodingProperty.Height };
    31             }
    32 
    33             return null;
    34         }
    35 
    36         private bool IsMatchingRatio(ImageEncodingProperties e)
    37         {
    38             double tolerance = 0.015;
    39             return Math.Abs(GetAspectRatio(e.Height, e.Width) - GetAspectRatio(desiredHeight, desiredWidth)) < tolerance;
    40         }
    41 
    42         private bool IsMatchingRatio(VideoEncodingProperties e)
    43         {
    44             double tolerance = 0.015;
    45             return Math.Abs(GetAspectRatio(e.Height, e.Width) - GetAspectRatio(desiredHeight, desiredWidth)) < tolerance;
    46         }
    47 
    48         private double GetAspectRatio(uint heiht, uint width)
    49         {
    50             return Math.Round((heiht != 0) ? (width / (double)heiht) : double.NaN, 2);
    51         }


    另外我决定采用的 LowLagPhotoCapture 来拍摄照片,可以调用 MediaCapture.PrepareLowLagPhotoCaptureAsync 初始化 LowLagPhotoCapture,初始化成功后就可以得到 LowLagPhotoCapture 对象。
    然后使用 CaptureAsync 来捕获低快门滞后照片,拍照成功后得到一个 CapturedPhoto 对象,该对象包含两个 CapturedFrame 对象,其中一个返回的是缩略图,另外一个正是我们需要的。
    最后使用 FinishAsync 释放 LowLagPhotoCapture 对象和资源,LowLagPhotoCapture 对象被释放后,再次拍照需要再次初始化。

     1 private LowLagPhotoCapture lowLagPhotoCapture;
     2 ...
     3 // Initialize MediaCapture
     4                 try
     5                 {
     6                     await mediaCapture.InitializeAsync(settings);
     7                     var imageEnCodingProperties = ImageEncodingProperties.CreatePng();
     8                     var resolution = await SetResolution(MediaStreamType.Photo);
     9                     if (resolution != null)
    10                     {
    11                         imageEnCodingProperties.Width = resolution[0];
    12                         imageEnCodingProperties.Height = resolution[1];
    13                     }
    14                     lowLagPhotoCapture = await mediaCapture.PrepareLowLagPhotoCaptureAsync(imageEnCodingProperties);
    15                     isInitialized = true;
    16                 }
    17                 catch (UnauthorizedAccessException)
    18                 {
    19                     await ShowMessage("Denied access to the camera.");
    20                 }
    21                 catch (Exception ex)
    22                 {
    23                     await ShowMessage("Exception when init MediaCapture. " + ex.Message);
    24                 }
    25 ...


    下一节将介绍采用ZXing.UWP来实现扫描二维码的功能。

  • 相关阅读:
    python2和3切换时的几个注意点会报错
    Python异常UnicodeEncodeError 'gbk' codec can't encode character 'xa0'
    python爬虫使用Xpath爬取指定位置的内容
    问题账户需求分析
    2018年春季个人阅读计划
    我们应当怎样做需求分析
    人月神话读后感3
    人月神话读后感2
    线程池
    生产者消费者
  • 原文地址:https://www.cnblogs.com/supperwu/p/7269847.html
Copyright © 2011-2022 走看看