如何设置 Flutter CameraPreview 大小“全屏”

Nav*_*mar 3 android flutter flutter-layout

我正在使用 CameraPreview 测量对象的高度,但问题是我无法全屏设置 cameraPreview 高度。

我试过Positioned widget,它填满了屏幕,但图像被拉伸了。我试过Transform Widget,但高度没有填满全屏,空白即将来临。图像没有被拉伸。

我的代码:

final size = MediaQuery.of(context).size;
final deviceRatio = size.width / size.height;

return Stack(
            children: <Widget>[
              Transform.scale(
                scale: controller.value.aspectRatio/deviceRatio,
                child: new AspectRatio(
                  aspectRatio: controller.value.aspectRatio,
                  child: new CameraPreview(controller),
                ),
              ),);
Run Code Online (Sandbox Code Playgroud)

请帮助我在没有图像拉伸的情况下安装 CameraPreview "FULLSCREEN"。

在此处输入图片说明

wan*_*pan 9

CameraValue.aspectRatio 返回宽度/高度而不是高度/宽度,因为0.7.0,CameraPreview 现在处理 AspectRatio 本身,所以 imo 工作代码片段如下:

/// only work inside WidgetsApp or MaterialApp, which introduces a MediaQuery
final scale = 1 / (controller.value.aspectRatio * MediaQuery.of(context).size.aspectRatio);
return Transform.scale(
  scale: scale,
  alignment: Alignment.topCenter,
  child: CameraPreview(controller),
);
Run Code Online (Sandbox Code Playgroud)

更新:

通过 Transform 缩放后,在TransitionRoute 中使用时,预览可能会超出屏幕大小限制。(当托管在 CupertinoPageRoute 中时,拖动手势将清楚地显示这一点)。

所以我认为剪辑预览以使其与屏幕尺寸完全匹配是个好主意。

final mediaSize = MediaQuery.of(context).size;
final scale = 1 / (controller.value.aspectRatio * mediaSize.aspectRatio);
return ClipRect(
  clipper: _MediaSizeClipper(mediaSize),
  child: Transform.scale(
    scale: scale,
    alignment: Alignment.topCenter,
    child: CameraPreview(controller),
  ),
);
class _MediaSizeClipper extends CustomClipper<Rect> {
  final Size mediaSize;
  const _MediaSizeClipper(this.mediaSize);
  @override
  Rect getClip(Size size) {
    return Rect.fromLTWH(0, 0, mediaSize.width, mediaSize.height);
  }
  @override
  bool shouldReclip(CustomClipper<Rect> oldClipper) {
    return true;
  }
}
Run Code Online (Sandbox Code Playgroud)


Luc*_*ens 8

尝试将 包裹CameraPreview在 a 中FittedBoxBoxFit.cover并确保父容器等于您要填充的空间。

@override
Widget build(BuildContext context) {
  final size = MediaQuery.of(context).size;

  return Scaffold(
      body: cameraController == null
          ? const Text("Loading Camera...")
          : Container(
              width: size.width,
              height: size.height,
              child: FittedBox(
                fit: BoxFit.cover,
                child: Container(
                    width: 100, // the actual width is not important here
                    child: CameraPreview(cameraController!)),
              )));
}
Run Code Online (Sandbox Code Playgroud)


Nav*_*mar 6

通过将 Center 小部件包装在 Transform 小部件中解决了问题

final size = MediaQuery.of(context).size;
final deviceRatio = size.width / size.height;
return Stack(
            children: <Widget>[
              Center(
                child:Transform.scale(
                      scale: controller.value.aspectRatio/deviceRatio,
                      child: new AspectRatio(
                       aspectRatio: controller.value.aspectRatio,
                       child: new CameraPreview(controller),
                       ),
                   ),),);
Run Code Online (Sandbox Code Playgroud)

  • 根据文章和上面的代码片段进行测试,图像被拉伸并且主要图像部分根本不显示。 (3认同)

小智 5

您可以通过根据 LayoutBuilder 的约束将 CameraPreview 包装在 LayoutBuilder 和 SizedBox 内来解决此问题,如下所示:

      LayoutBuilder(
        builder: (context, constraints) {
          return SizedBox(
            width: constraints.maxWidth,
            height: constraints.maxHeight,
            child: CameraPreview(controller),
          );
        },
      ),
Run Code Online (Sandbox Code Playgroud)

它会像魅力一样发挥作用

  • 不起作用,图像被拉伸 (4认同)