UWP应用MediaCapture相机预览尺寸异常问题求助
嘿,我之前在做UWP相机应用的时候,也碰到过Lumia 950上MediaCapture预览尺寸异常和对焦模糊的问题,结合踩过的坑,给你几个靠谱的解决方案:
一、解决预览画面过小的问题
Lumia 950的前后置相机支持超多分辨率档位,MediaCapture默认会选兼容性最高但尺寸极小的分辨率,这就是为啥后置相机预览特别小的原因。我们需要手动指定和预览控件匹配的最优分辨率:
1. 获取并筛选相机支持的预览分辨率
首先要拿到相机所有可用的预览配置,然后筛选出和你的预览控件宽高比一致的选项,再挑最合适的尺寸:
private static MediaEncodingProfile GetMatchingPreviewProfile(MediaCapture mediaCapture, double targetWidth, double targetHeight) { // 获取所有可用的预览流配置 var allPreviewProps = mediaCapture.VideoDeviceController .GetAvailableMediaStreamProperties(MediaStreamType.VideoPreview) .OfType<VideoEncodingProperties>() .ToList(); // 计算目标宽高比(统一处理横竖屏,避免方向导致的比例不匹配) double targetAspectRatio = targetWidth / targetHeight; if (targetAspectRatio < 1) targetAspectRatio = 1 / targetAspectRatio; // 筛选同宽高比的配置,按分辨率从大到小排序 var matchingProps = allPreviewProps.Where(prop => { double propAspectRatio = (double)prop.Width / prop.Height; if (propAspectRatio < 1) propAspectRatio = 1 / propAspectRatio; // 允许0.01的误差,避免因小数精度问题过滤掉匹配项 return Math.Abs(propAspectRatio - targetAspectRatio) < 0.01; }) .OrderByDescending(prop => prop.Width * prop.Height) .ToList(); // 优先选不超过控件尺寸的最大分辨率,没有的话就选同比例里最大的 if (matchingProps.Any()) { var bestMatch = matchingProps.FirstOrDefault(p => p.Width <= targetWidth && p.Height <= targetHeight) ?? matchingProps.First(); return MediaEncodingProfile.CreateMp4(bestMatch.Width, bestMatch.Height); } // 兜底用控件尺寸的默认配置 return MediaEncodingProfile.CreateMp4((uint)targetWidth, (uint)targetHeight); }
2. 初始化时设置预览分辨率
在你的MediaCapture初始化完成后,调用上面的方法设置预览流:
// 假设你的预览控件叫PreviewControl var previewProfile = GetMatchingPreviewProfile(_mediaCapture, PreviewControl.ActualWidth, PreviewControl.ActualHeight); await _mediaCapture.SetPreviewMediaStreamAsync(previewProfile);
3. 适配设备旋转
Lumia 950是手机,旋转屏幕时要同步调整预览的旋转角度,避免画面错位:
private async void DisplayInformation_OrientationChanged(DisplayInformation sender, object args) { if (_mediaCapture == null) return; VideoRotation videoRotation = sender.CurrentOrientation switch { DisplayOrientations.Portrait => VideoRotation.Clockwise90Degrees, DisplayOrientations.LandscapeFlipped => VideoRotation.Clockwise180Degrees, DisplayOrientations.PortraitFlipped => VideoRotation.Clockwise270Degrees, _ => VideoRotation.None }; await _mediaCapture.SetPreviewRotationAsync(videoRotation); }
记得在初始化时注册这个事件:
DisplayInformation.GetForCurrentView().OrientationChanged += DisplayInformation_OrientationChanged;
二、解决对焦模糊的问题
Lumia 950的相机默认对焦模式可能不是连续自动对焦,而且启动预览时不会自动触发对焦,导致画面模糊。可以通过以下方式修复:
1. 设置连续自动对焦
在MediaCapture初始化完成后,配置对焦控件为连续自动对焦模式:
var focusControl = _mediaCapture.VideoDeviceController.FocusControl; if (focusControl.Supported && focusControl.Modes.Contains(FocusMode.Continuous)) { await focusControl.ConfigureAsync(new FocusSettings { Mode = FocusMode.Continuous, AutoFocusRange = AutoFocusRange.FullRange, DisableDriverFallback = false }); // 手动触发一次对焦,确保预览启动时画面清晰 await focusControl.FocusAsync(); }
2. 添加点击对焦功能(可选)
如果用户需要手动对焦某个区域,可以给预览控件添加点击事件:
private async void PreviewControl_Tapped(object sender, TappedRoutedEventArgs e) { var focusControl = _mediaCapture.VideoDeviceController.FocusControl; if (!focusControl.Supported) return; // 获取点击位置,转换为相机的归一化坐标(0-1范围) var tapPoint = e.GetPosition(PreviewControl); var normalizedPoint = new Point( tapPoint.X / PreviewControl.ActualWidth, tapPoint.Y / PreviewControl.ActualHeight ); // 触发点击位置的对焦 await focusControl.FocusAsync(normalizedPoint); }
三、额外注意事项
- 预览控件的拉伸模式:把
PreviewControl的Stretch属性设为Uniform,同时设置HorizontalAlignment="Stretch"和VerticalAlignment="Stretch",确保画面占满控件且不变形。 - 权限检查:一定要在
Package.appxmanifest里声明webcam和microphone权限,并且在代码启动时主动请求权限,否则相机的部分功能会被限制。
内容的提问来源于stack exchange,提问作者Adrián Molčan
相关产品推荐
相关产品推荐

