You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 05:57:02