如何在 Flutter 中裁剪图像?

How do I crop an image in Flutter?

假设我有一个矩形的纵向图像:

我想裁剪它,使其呈现如下:

我如何在 Flutter 中执行此操作?

(我不需要调整图片大小。)

(图片来自https://flic.kr/p/nwXTDb

看看 brendan-duncan/image,它是一个独立于平台的库,用于在 Dart 中操作图像。

您可以使用函数:

Image copyCrop(Image src, int x, int y, int w, int h);

如果您不想在 Container 上硬编码高度,我可能会使用 BoxDecoration with a DecorationImage. You can use the alignment and fit properties to determine how your image is cropped. You can use an AspectRatio 小部件。

import 'package:flutter/material.dart';

void main() {
  runApp(new MaterialApp(
    home: new MyHomePage(),
  ));
}

class MyHomePage extends StatelessWidget {

  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("Image Crop Example"),
      ),
      body: new Center(
        child: new AspectRatio(
          aspectRatio: 487 / 451,
          child: new Container(
            decoration: new BoxDecoration(
              image: new DecorationImage(
                fit: BoxFit.fitWidth,
                alignment: FractionalOffset.topCenter,
                image: new NetworkImage('https://i.stack.imgur.com/lkd0a.png'),
              )
            ),
          ),
        ),
      ),
    );
  }
}

您也可以直接使用 Image class with BoxFit 并执行以下操作:

new Image.asset(
  stringToImageLocation,
  fit: BoxFit.cover,
)

有一个名为 ImageCropper 的新包。我建议大家改用它,因为它具有许多功能并且使一切变得更容易。它允许您将图像裁剪为您想要的任何或指定的纵横比,甚至可以压缩图像。这是包裹的 link:https://pub.dev/packages/image_cropper

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:image_cropper/image_cropper.dart';

class MyPage extends StatefulWidget {
  @override
  _MyPageState createState() => _MyPageState();
}

class _MyPageState extends State<MyPage> {
  /// Variables
  File imageFile;

  /// Widget
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          backgroundColor: Color(0XFF307777),
          title: Text("Image Cropper"),
        ),
        body: Container(
            child: imageFile == null
                ? Container(
                    alignment: Alignment.center,
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget>[
                        RaisedButton(
                          color: Color(0XFF307777),
                          onPressed: () {
                            _getFromGallery();
                          },
                          child: Text(
                            "PICK FROM GALLERY",
                            style: TextStyle(color: Colors.white),
                          ),
                        ),
                      ],
                    ),
                  )
                : Container(
                    child: Image.file(
                      imageFile,
                      fit: BoxFit.cover,
                    ),
                  )));
  }

  /// Get from gallery
  _getFromGallery() async {
    PickedFile pickedFile = await ImagePicker().getImage(
      source: ImageSource.gallery,
      maxWidth: 1800,
      maxHeight: 1800,
    );
    _cropImage(pickedFile.path);
  }

  /// Crop Image
  _cropImage(filePath) async {
    File croppedImage = await ImageCropper.cropImage(
      sourcePath: filePath,
      maxWidth: 1080,
      maxHeight: 1080,
    );
    if (croppedImage != null) {
      imageFile = croppedImage;
      setState(() {});
    }
  }
}

为您的 Image 小部件提供 fit 因子,然后将其包装在 AspectRatio 中。

AspectRatio(
  aspectRatio: 1.5, 
  child: Image.asset(
    'your_image_asset',
    fit: BoxFit.cover,
  ),
)

仅使用这两个属性为我工作:

CachedNetworkImage(
  fit: BoxFit.cover,// OR BoxFit.fitWidth
  alignment: FractionalOffset.topCenter,
  ....
)