我正在try 在我的应用程序中拍摄方形照片.我使用的是camera软件包,我试图显示CameraPreview小部件的一个中心方形裁剪版本.

我的目标是显示预览的中心正方形(全宽),从顶部和底部裁剪成均匀的数量.

我一直在努力使其正常工作,所以我使用固定图像创建了一个最小的示例.(为我坐在椅子上的沉闷照片道歉):

import 'package:flutter/material.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Example',
      theme: ThemeData(),
      home: Scaffold(
        body: Example(),
      ),
    );
  }
}

class Example extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        CroppedCameraPreview(),

        // Something to occupy the rest of the space
        Expanded(
          child: Container(),
        )
      ],
    );
  }
}

class CroppedCameraPreview extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // We will pretend this is a camera preview (to make demo easier)
    var cameraImage = Image.network("https://i.imgur.com/gZfg4jm.jpg");
    var aspectRatio = 1280 / 720;

    return Container(
      width: MediaQuery.of(context).size.width,
      height: MediaQuery.of(context).size.width,
      child: ClipRect(
        child: new OverflowBox(
          alignment: Alignment.center,
          child: FittedBox(
            fit: BoxFit.fitWidth,
            child: cameraImage,
          ),
        ),
      ),
    );
  }
}

这很好用-我得到了一个全屏幕宽度的图像,中间被裁剪,并被推到我的应用程序的顶部.

然而,如果我把这段代码放到我现有的应用程序中,用CameraPreview替换cameraImage,我会得到很多布局错误:

flutter: ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
flutter: The following assertion was thrown during performResize():
flutter: TextureBox object was given an infinite size during layout.
flutter: This probably means that it is a render object that tries to be as big as possible, but it was put
flutter: inside another render object that allows its children to pick their own size.
flutter: The nearest ancestor providing an unbounded width constraint is:
flutter:   RenderFittedBox#0bd54 NEEDS-LAYOUT NEEDS-PAINT
flutter:   creator: FittedBox ← OverflowBox ← ClipRect ← ConstrainedBox ← Container ← Stack ← ConstrainedBox
flutter:   ← Container ← CameraWidget ← Column ← CameraPage ← MediaQuery ← ⋯
flutter:   parentData: offset=Offset(0.0, 0.0) (can use size)
flutter:   constraints: BoxConstraints(w=320.0, h=320.0)
flutter:   size: MISSING
flutter:   fit: fitWidth
flutter:   alignment: center
flutter:   textDirection: ltr
flutter: The nearest ancestor providing an unbounded height constraint is:
flutter:   RenderFittedBox#0bd54 NEEDS-LAYOUT NEEDS-PAINT
flutter:   creator: FittedBox ← OverflowBox ← ClipRect ← ConstrainedBox ← Container ← Stack ← ConstrainedBox
flutter:   ← Container ← CameraWidget ← Column ← CameraPage ← MediaQuery ← ⋯
flutter:   parentData: offset=Offset(0.0, 0.0) (can use size)
flutter:   constraints: BoxConstraints(w=320.0, h=320.0)
flutter:   size: MISSING
flutter:   fit: fitWidth
flutter:   alignment: center
flutter:   textDirection: ltr
flutter: The constraints that applied to the TextureBox were:
flutter:   BoxConstraints(unconstrained)
flutter: The exact size it was given was:
flutter:   Size(Infinity, Infinity)
flutter: See https://flutter.io/layout/ for more information.

有人能告诉我为什么预览会出错,以及如何避免错误吗?

推荐答案

我解决了这个问题,为我的CameraPreview个实例指定了一个特定的大小,将其包装在Container中:

  var size = MediaQuery.of(context).size.width;

  // ...

  Container(
    width: size,
    height: size,
    child: ClipRect(
      child: OverflowBox(
        alignment: Alignment.center,
        child: FittedBox(
          fit: BoxFit.fitWidth,
          child: Container(
            width: size,
            height:
                size / widget.cameraController.value.aspectRatio,
            child: camera, // this is my CameraPreview
          ),
        ),
      ),
    ),
  );

为了响应Luke的 comments ,我随后使用此代码对结果图像进行了方形裁剪.(因为即使预览是方形的,捕获的图像仍然是标准比例).

  Future<String> _resizePhoto(String filePath) async {
      ImageProperties properties =
          await FlutterNativeImage.getImageProperties(filePath);

      int width = properties.width;
      var offset = (properties.height - properties.width) / 2;

      File croppedFile = await FlutterNativeImage.cropImage(
          filePath, 0, offset.round(), width, width);

      return croppedFile.path;
  }

这使用https://github.com/btastic/flutter_native_image.我已经有一段时间没有使用这个代码了--我想它目前只适用于肖像图像,但应该可以很容易地扩展到处理风景.

Flutter相关问答推荐

Flutter bloc -如何使用BlocBuilder?

如何在应用栏中将列置于中心

当MyChangeNotifier更改时如何计算函数,而无需在构建方法中进行不必要的调用- Flutter

如何解决这个错误,同时获得的高度的小部件,因此高度的可用工作区域在Flutter ?

使用ThemeProvider不在亮模式和暗模式之间切换

Flutter 中的多页表现

BlocBuilder仅生成一次,并在后续发出时停止重建

BaseInputfield和Textfield有什么不同?

当我转到其他屏幕并按下后退按钮时,屏幕将不会刷新

运行调试flutter应用程序时出错:B/BL超出范围(最大+/-128MB)到'';

Riverpod Provider.family 和 HookConsumerWidget 不刷新 UI

从所有设备注销,因为用户帐户已从 firebase flutter 中删除

什么最接近 Dart 的 List.asMap().forEach() 返回列表?

Flutterfire Configure - 未处理的异常和没有 firebase 初始化

Flutter HLS .m3u8 视频无法实时播放

在 flutter 中使用 StreamBuilder 在文本字段中键入时显示过滤记录

如何在Flutter 中根据其父小部件高度设置图标按钮飞溅半径

扫描flutter生成的二维码后如何弹出文本字段值

如何将变量翻译成其他语言

try 为两个下拉值添加共享首选项,但在 Flutter 上显示错误断言失败:?