如何使用Flutter camera插件设置CameraPreview尺寸避免拉伸及输出图尺寸不符
解决方案
一、预览拉伸问题修复
当前代码出现拉伸的核心原因是:相机原生的预览比例和你设定的500:75(约6.67:1)的容器比例不匹配,BoxFit.fitWidth会强制将相机预览拉伸到匹配容器宽度,高度被强行压缩导致变形。
正确的处理逻辑是保持相机预览的原生比例不变,仅裁剪超出容器的部分,视觉上不会出现拉伸,修改后的代码如下:
// 先定义目标容器的宽高比,500宽75高的比例为500/75≈6.6667 final double targetAspectRatio = 500 / 75; Container( height: Get.height * 0.1, width: Get.width * 0.8, decoration: const BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(10.0)), ), child: ClipRRect( borderRadius: BorderRadius.circular(10), child: OverflowBox( alignment: Alignment.center, child: FittedBox( // 改用BoxFit.cover保证铺满容器,保持原生比例不变,超出部分自动裁剪 fit: BoxFit.cover, child: SizedBox( width: Get.width * 0.8, // 高度按目标比例计算,而非相机原生比例 height: (Get.width * 0.8) / targetAspectRatio, child: CameraPreview( Get.find<CameraScannerController>().controller.value ), ), ), ), ), );
二、输出图片尺寸不符合预设问题修复
Camera插件的原生输出尺寸是初始化相机时选择的预设尺寸,和预览容器尺寸无关,需要在拿到拍摄的图片数据后,手动裁剪到你需要的500*75规格,示例处理逻辑如下:
- 先添加
image依赖到pubspec.yaml,用于图片处理 - 裁剪示例代码:
import 'package:image/image.dart' as img; Future<img.Image> cropToTargetSize(img.Image rawImage) async { final double rawAspectRatio = rawImage.width / rawImage.height; int cropWidth, cropHeight; // 先按目标比例裁剪居中区域 if (rawAspectRatio > targetAspectRatio) { // 原图更宽,裁剪左右多余区域 cropHeight = rawImage.height; cropWidth = (cropHeight * targetAspectRatio).round(); } else { // 原图更高,裁剪上下多余区域 cropWidth = rawImage.width; cropHeight = (cropWidth / targetAspectRatio).round(); } final croppedImage = img.copyCrop( rawImage, x: (rawImage.width - cropWidth) ~/ 2, y: (rawImage.height - cropHeight) ~/ 2, width: cropWidth, height: cropHeight, ); // 缩放到你需要的精确尺寸500*75 return img.copyResize(croppedImage, width: 500, height: 75); }
注意:如果拍摄出来的图片方向不对,需要先调用
img.copyRotate调整旋转角度后再做裁剪,避免裁剪区域偏移。
内容的提问来源于stack exchange,提问作者jux_97
相关产品推荐
相关产品推荐

