Flutter中如何将Camera Preview设置为无拉伸的全屏显示效果
camera 0.9.4+5版本无拉伸全屏预览设置方案
该版本确实调整了默认预览尺寸的计算逻辑,不再优先适配屏幕比例,按照以下步骤操作即可实现无拉伸全屏显示:
第一步:计算目标宽高比
通过MediaQuery获取当前设备的屏幕尺寸,计算目标比例:targetAspectRatio = 屏幕宽度 / 屏幕高度,横屏场景下需要调换宽高计算。第二步:筛选相机支持的最优分辨率
拿到CameraController实例前,遍历相机支持的所有分辨率,找到和targetAspectRatio差值最小、分辨率最高的选项,避免预览模糊或比例不匹配:
double targetRatio = MediaQuery.of(context).size.aspectRatio; double minRatioDiff = double.infinity; Resolution? bestResolution; for (var res in cameraDescription.resolutions) { double currentRatio = res.width / res.height; double diff = (currentRatio - targetRatio).abs(); if (diff < minRatioDiff) { minRatioDiff = diff; bestResolution = res; } }
初始化控制器时传入筛选到的最优分辨率:
CameraController controller = CameraController( cameraDescription, bestResolution ?? ResolutionPreset.max, imageFormatGroup: ImageFormatGroup.yuv420, ); await controller.initialize(); // 强制设置预览比例,避免系统默认修改 await controller.setPreviewAspectRatio(controller.value.aspectRatio);
- 第三步:适配预览渲染
渲染CameraPreview时使用BoxFit.cover模式铺满容器,超出屏幕的边缘会被自动裁剪,不会出现拉伸变形:
LayoutBuilder( builder: (context, constraints) { return AspectRatio( aspectRatio: constraints.maxWidth / constraints.maxHeight, child: FittedBox( fit: BoxFit.cover, child: SizedBox( // 注意相机预览默认是竖屏比例,宽高要反取 width: controller.value.previewSize?.height ?? 0, height: controller.value.previewSize?.width ?? 0, child: CameraPreview(controller), ), ), ); } )
注意事项
- 横竖屏切换时需要重新计算目标比例、刷新控制器配置,避免切换后出现拉伸
- iOS部分老旧机型仅支持固定比例的预览,此时可以接受小范围裁剪,不要强制匹配屏幕比例避免出现黑边
内容的提问来源于stack exchange,提问作者Super Coder
相关产品推荐
相关产品推荐

