How To Scan QRCode For UWP (3)

這一節主要介紹如何去設置MediaCapture拍照的分辨率。async

MediaCapture 包含一個 VideoDeviceController對象,憑藉它能夠控制攝像頭的不少設置,其中包括設置拍照的分辨率。 首先經過GetAvailableMediaStreamProperties方法來獲取設備所支持的 Encoding Properties,要注意的是即便你指定了MediaStreamType爲Photo,這個API也會有可能同時返回 ImageEncodingProperties /VideoEncodingProperties對象。 所以咱們在比較設備支持的Encoding Properties,須要手動去將它強制轉換爲 ImageEncodingProperties/VideoEncodingProperties對象。 此外還須要找到寬高比很是接近咱們所指望的分辨率,偏差範圍在0.015以內。示例代碼使用的寬高比爲16:9,常見的還有4:3。ide

比較奇怪的IMediaEncodingProperties沒有聲明Width/Height屬性,讓代碼寫的有點囉嗦。ui

 實現代碼以下:spa

 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 對象被釋放後,再次拍照須要再次初始化。code

 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來實現掃描二維碼的功能。對象

相關文章
相關標籤/搜索