首页 > 代码库 > How To Scan QRCode For UWP (3)

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 <= desiredWidth13                                                                         && 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 <= desiredWidth24                                                                       && 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来实现扫描二维码的功能。

How To Scan QRCode For UWP (3)