如何方形裁剪 Flutter 相机预览 [英] How to square crop a Flutter camera preview

查看:64
本文介绍了如何方形裁剪 Flutter 相机预览的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在我的应用中拍摄方形照片.我正在使用 camera 包,我正在尝试显示中心正方形裁剪版本的CameraPreview 小部件.

I'm trying to take square pictures in my app. I'm using the camera package and I'm trying to display a centre square-cropped version of the CameraPreview widget.

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

My goal is to show the central square of the preview (full width), with an even amount cropped from the top and bottom.

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

I was struggling to get this to work, so I created a minimal example using a fixed image. (Apologies for the dull picture of me in a chair):

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,
          ),
        ),
      ),
    );
  }
}

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

This works fine - I get a full screen width image, centre cropped and pushed to the top of my app.

但是,如果我将此代码放入我现有的应用程序中并将 cameraImage 替换为 CameraPreview,则会出现很多布局错误:

However, if I drop this code into my existing app and replace cameraImage with a CameraPreview, I get a lot of layout errors:

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.

谁能告诉我为什么我在预览时遇到错误以及如何避免它们?

Can anyone suggest why I'm getting errors with the preview and how to avoid them?

推荐答案

我通过给我的 CameraPreview 实例一个特定的大小,将它包装在一个 Container 中解决了这个问题:

I solved this by giving a specific size to my CameraPreview instance, by wrapping it in a 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 的评论,我然后使用此代码对生成的图像进行方形裁剪.(因为即使预览是方形的,拍摄的图像仍然是标准比例).

To respond to Luke's comment, I then used this code to square crop the resulting image. (Because even though the preview is square, the image captured is still standard ratio).

  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.自从我使用此代码以来已经有一段时间了 - 认为它目前仅适用于纵向图像,但应该可以轻松扩展以处理横向.

This uses https://github.com/btastic/flutter_native_image. It's been a while since I used this code - think it currently just works for portrait images, but should easily be extendable to handle landscape.

这篇关于如何方形裁剪 Flutter 相机预览的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆