flutter camera -CameraPreview(controller)和controller.buildPreiview()有什么区别

6kkfgxo0  于 2023-05-23  发布在  Flutter
关注(0)|答案(2)|浏览(125)

我是新的Flutter,我试图使用相机与Flutter。
我想了解CameraPreview(controller)controller.buildPreiview()之间的区别,因为出于某种原因,它的行为不同。
这是显示预览的代码:

@override
  Widget build(BuildContext context) {
    return _isCameraInitialized
        ? Material(
            child: Stack(
                children: [
                  GestureDetector(
                    ...
                    child: _cameraController!.buildPreview()
                    // child: CameraPreview(_cameraController!)
                  ),
                  ....
                ]
            ),
        )
        : Container();

使用_cameraController!.buildPreview()的结果:

这是所需的结果-使相机预览显示为全屏。
但是使用CameraPreview(_cameraController!)的结果是:

这使得屏幕右侧为白色,并且由于某种原因没有占用屏幕的全部宽度。我也试着用AspectRatio Package 它,但它没有工作。
我想知道为什么这些方法的行为不同,是否使用其中一个比另一个更好?

k97glaaz

k97glaaz1#

使用此解决方案,它将删除右垂直横幅:

width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child:CameraPreview(_cameraController),
ztigrdn8

ztigrdn82#

CameraPreview(controller)实际上是在其build(context)方法中调用controller.buildPreview(),但 Package 在AspectRatio小部件中并设置为以下长宽比:

  1. previewSize!.width / previewSize!.height,如果设备方向为横向,或
  2. 1 / previewSize!.width / previewSize!.height如果是纵向。
    其中previewSizeCameraController的目标(或更低)分辨率预设。
// camera_preview.dart (as on 23 May 2023)

class CameraPreview extends StatelessWidget {
  const CameraPreview(this.controller, {super.key, this.child});

  final CameraController controller;

  final Widget? child;

  @Override
  Widget build(BuildContext context) {
    return controller.value.isInitialized
        ? ValueListenableBuilder<CameraValue>(
            valueListenable: controller,
            builder: (BuildContext context, Object? value, Widget? child) {
              return AspectRatio(
                aspectRatio: _isLandscape()
                    ? controller.value.aspectRatio
                    : (1 / controller.value.aspectRatio),
                child: Stack(
                  fit: StackFit.expand,
                  children: <Widget>[
                    _wrapInRotatedBox(child: controller.buildPreview()),
                    child ?? Container(),
                  ],
                ),
              );
            },
            child: child,
          )
        : Container();
  }
  // ...
}

完整的源代码请参考camera_preview.dart
在查看下面的controller.buildPreview()代码时:

// camera_controller.dart (as on 23 May 2023)

Widget buildPreview() {
  _throwIfNotInitialized('buildPreview');
  try {
    return CameraPlatform.instance.buildPreview(_cameraId);
  } on PlatformException catch (e) {
    throw CameraException(e.code, e.message);
  }
}

它从MethodChannelCamera调用buildPreview(cameraId)方法,CameraPlatform的实现使用方法通道,并返回Texture小部件:

// method_channel_camera.dart (as on 23 May 2023)

@override
Widget buildPreview(int cameraId) {
  return Texture(textureId: cameraId);
}

the class doc中,Texture小部件是
后端纹理Map到的矩形。
后端纹理是可以应用(Map)到Flutter视图区域的图像。它们是使用特定于平台的纹理注册表创建、管理和更新的。这通常由与主机平台视频播放器、相机或OpenGL API或类似图像源集成的插件来完成。
因此,总而言之,两者之间的主要区别在于CameraPreview(controller)尊重预设分辨率的纵横比,而controller.buildPreview()不是并且总是满足给定的大小约束。

相关问题