首页 > 解决方案 > 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();
      });
    });
  }

标签: androidfluttercamera

解决方案


实际上,实现 CameraController 的 Java 端的底层 CameraPlugin 类试图保持预览和捕获图像的纵横比一致。通常,在本机代码中,人们会忘记这一点,因为本机 API 无法帮助开发人员保持图片和预览的纵横比同步。这可能会导致您观察到的结果,捕获的 Jpeg 为 16:9,预览为 4:3,并且此类静止图片的视野将比预览更宽。

但正如您在链接的 Java 代码中看到的那样,Flutter 相机实际上(几乎)是正确编写的。一个问题是比较浮点数可能会导致令人讨厌的舍入效果。他们的goodEnough预览分辨率列表可能会被搞砸,因为他们要求预览宽度小于屏幕宽度(在纵向模式下,它可能低至 720)。

无论如何,您可以检查initialize()返回的预览大小,很可能是 16:9,与 Jpeg 相同。

顺便说一句,我相信您错误地使用了.png扩展名,并且实际图像在 sdcard 上保存为 Jpeg。


推荐阅读