1. 程式人生 > >How To Scan QRCode For UWP (3)

How To Scan QRCode For UWP (3)

reat 通過 color 照片 property create null 同時 exce

這一節主要介紹如何去設置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來實現掃描二維碼的功能。

How To Scan QRCode For UWP (3)