android - Flutter - 为什么从相机控制器获得的图像比在 cameraPreview 上的更宽?
问题描述
我正在使用颤振的相机包,我注意到从takePicture()
函数获得的图像比预览模式下显示的要宽。此外,垂直拍摄的照片看起来是方形的。我应该自己后处理吗?原生安卓开发也一样吗?
构建方法代码
@override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
body: Stack(
children: <Widget>[
FutureBuilder<void>(
future: _initializeControllerFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return Stack(
alignment: FractionalOffset.center,
children: <Widget>[
new Positioned.fill(
child: _getCameraPreview(context),
),
new Positioned.fill(
child: new Opacity(
opacity: 0.7,
child: Image.asset(
_layoutPath,
scale: 5,
fit: BoxFit.none,
alignment: Alignment(0.2, 0.1),
)),
),
],
);
} else {
return Center(child: CircularProgressIndicator());
}
},
),
Align(
alignment: Alignment.bottomCenter,
child: BottomAppBar(
color: Color.fromARGB(0, 0, 0, 0),
child: _getBottomAppBarRow(context),
),
),
],
),
);
}
_getCameraPreview(BuildContext context) {
final size = MediaQuery.of(context).size;
final deviceRatio = size.width / size.height;
return Transform.scale(
scale: _controller.value.aspectRatio / deviceRatio,
child: Center(
child: AspectRatio(
aspectRatio: _controller.value.aspectRatio,
child: CameraPreview(_controller),
),
),
);
}
快门按钮代码
final shutterButton = Material(
elevation: 5.0,
borderRadius: BorderRadius.circular(30.0),
color: AppColors.white,
child: FloatingActionButton(
child: Icon(
Icons.camera,
color: AppColors.white,
size: 24,
),
onPressed: () async {
try {
await _initializeControllerFuture;
final path = join(
(await getTemporaryDirectory()).path,
'${DateTime.now()}.png',
);
await _controller.takePicture(path);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DisplayPictureScreen(imagePath: path),
),
);
_controller.dispose();
} catch (e) {
print(e);
}
},
),
);
编辑:
相机控制器初始化代码:
CameraController _controller;
Future<void> _initializeControllerFuture;
var _firstCamera;
var _layoutPath = 'images/cie-on-50.png';
@override
void initState() {
super.initState();
availableCameras().then((cameras) {
setState(() {
_firstCamera = cameras.first;
_controller = CameraController(_firstCamera, ResolutionPreset.high);
_initializeControllerFuture = _controller.initialize();
});
});
}
解决方案
实际上,实现 CameraController 的 Java 端的底层 CameraPlugin 类试图保持预览和捕获图像的纵横比一致。通常,在本机代码中,人们会忘记这一点,因为本机 API 无法帮助开发人员保持图片和预览的纵横比同步。这可能会导致您观察到的结果,捕获的 Jpeg 为 16:9,预览为 4:3,并且此类静止图片的视野将比预览更宽。
但正如您在链接的 Java 代码中看到的那样,Flutter 相机实际上(几乎)是正确编写的。一个问题是比较浮点数可能会导致令人讨厌的舍入效果。他们的goodEnough预览分辨率列表可能会被搞砸,因为他们要求预览宽度小于屏幕宽度(在纵向模式下,它可能低至 720)。
无论如何,您可以检查initialize()返回的预览大小,很可能是 16:9,与 Jpeg 相同。
顺便说一句,我相信您错误地使用了.png扩展名,并且实际图像在 sdcard 上保存为 Jpeg。
推荐阅读
- r - 在 r 闪亮的模块中使用反应值
- algorithm - 这种朴素的素数分解算法有多快?
- javascript - Mocha 测试需要 done() 来结束,但随后会说“解决方法被过度指定。指定回调*或*返回 Promise;不是两者。”
- laravel - Laravel 6 - 如何通过用户字段值限制路由?
- matplotlib - 使用 Geopandas 绘制带有离散颜色条/图例的等值线图
- javascript - ReactJS - 状态变量行为异常
- typescript - 有没有办法让 VS Code 将 TypeScript 三斜杠指令添加到 VS Code 中 TS 文件的顶部?
- php - Laravel 5.8:beberlei/assert/lib/Assert/functions.php 返回类型产生错误
- swift - 如何将方法标记为“必需”
- python - 在 Pandas Dataframe 中为特定列查找其他值之间的值