如何使用Media Foundation修复拍摄高分辨率照片过曝问题
高分辨率快照过曝修复方案
核心原因
你遇到的过曝问题本质是Surface系列等搭载专用高分辨率照片流的设备,预览流和照片流使用独立的ISP处理通道,你对预览流配置的IAMCameraControl、IAMVideoProcAmp参数不会自动同步到照片流,且缺少系统相机默认执行的预捕获校准步骤。
可落地修复方案
1. 配置照片流专属的3A参数
不要用预览流的控制接口,通过IMFGetService查询照片流专属的控制接口调整参数:// 在Initialize CaptureEngine之后添加 IMFGetService getService = captureEngine as IMFGetService; Guid photoServiceGuid = new Guid(MFConstants.MF_CAPTURE_ENGINE_PHOTO_STREAM_SERVICE); IAMCameraControl photoCameraControl = null; getService.GetService(photoServiceGuid, typeof(IAMCameraControl).GUID, out object photoControlObj); photoCameraControl = photoControlObj as IAMCameraControl; // 先开启自动曝光,触发一次曝光校准再锁定 photoCameraControl.Set(CameraControlProperty.Exposure, CameraControlFlags.Auto, 0); // 等待200ms让AE收敛,也可以监听MF_CAPTURE_ENGINE_EXPOSURE_COMPLETED事件 Thread.Sleep(200); // 锁定曝光避免拍照时ISP自动调整 photoCameraControl.Set(CameraControlProperty.Exposure, CameraControlFlags.Manual, currentExposureValue);2. 增加预捕获校准步骤
系统相机在拍摄高分辨率照片前会执行预捕获流程,完成高分辨率模式下的曝光、对焦、白平衡校准,你需要在TakePhoto前添加该步骤:// 在SetSampleCallback之后,TakePhoto之前添加 captureEngine.PreparePhotoSequence(sinkStreamIndex); // 等待MF_CAPTURE_ENGINE_PREPARE_PHOTO_SEQUENCE_COMPLETED事件回调 captureEngineOnEventCallback.WaitUntilPrepareDone();3. 修正照片媒体类型的颜色空间参数
很多高分辨率照片流默认输出线性颜色空间,直接按照常规伽马2.2解码会导致过曝,需要在CreatePhotoMediaType方法中补充以下属性配置:// 配置为BT.709颜色空间,和系统相机输出一致 photoMediaType.SetUINT32(MFAttributesClsid.MF_MT_TRANSFER_FUNCTION, (uint)MFVideoTransferFunction.MFVideoTransferFunction_709); photoMediaType.SetUINT32(MFAttributesClsid.MF_MT_VIDEO_PRIMARIES, (uint)MFVideoPrimaries.MFVideoPrimaries_BT709); // 禁用ISP的自动增益拉高 photoMediaType.SetUINT32(MFAttributesClsid.MF_MT_AUTO_GAIN_CONTROL, 0);4. 确认选择正确的高分辨率媒体类型
同分辨率下设备可能提供多个媒体类型,仅系统相机选用的类型会默认匹配最优曝光参数,选择时优先满足以下条件:- 格式为NV12或MJPG(避免RAW格式未做伽马校正)
MF_MT_AM_FORMAT_TYPE值为FORMAT_VideoInfo2- 帧率和预览流帧率一致,避免ISP为高分辨率模式强制提升增益
问题相关参考
过曝快照示例

设备高分辨率照片选项

内容的提问来源于stack exchange,提问作者Bruno V
相关产品推荐
相关产品推荐

