这一节主要介绍如何去设置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 TaskSetResolution(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 }
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 ...