Flutter图片裁剪插件image_cropping的使用

发布于 1周前 作者 sinazl 来自 Flutter

Flutter图片裁剪插件image_cropping的使用

插件简介

image_cropping 是一个支持多平台的Flutter插件,主要用于实现图片的裁剪和旋转功能。它允许用户在裁剪时包含背景、调整选择区域的比例以及旋转图片。

Image Plugin

功能特性

  • 允许包含背景:可以在裁剪界面中显示图片的背景。
  • 旋转图片:用户可以旋转图片以获得所需的角度。
  • 更改选择比例:可以根据需求更改裁剪框的比例。

Image Plugin Image Plugin

安装

添加依赖

pubspec.yaml 文件中添加以下依赖:

dependencies:
  image_cropping: ^latest_version

确保替换 latest_version 为最新版本号。可以通过 Pub Dev 获取最新版本信息。

Web平台注意事项

如果你的目标平台包括Web,请确保在项目的根目录下添加 worker.js 文件。你可以通过以下命令生成这些文件:

dart compile js -O1 -o web/worker.js lib/worker.dart

更多关于该命令的信息可以参考 Dart官方文档

示例代码

下面是一个完整的示例项目,展示了如何使用 image_cropping 插件进行图片选择和裁剪。

import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:image_cropping/image_cropping.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';

void main() {
  runApp(
    MaterialApp(
      debugShowCheckedModeBanner: false,
      builder: EasyLoading.init(),
      home: MyApp(),
    ),
  );
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
  Uint8List? imageBytes;

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        body: Container(
          color: Colors.grey[200],
          child: Center(
            child: InkWell(
              child: imageBytes == null
                  ? Icon(Icons.add_photo_alternate_outlined, size: 50, color: Colors.black,)
                  : Image.memory(imageBytes!),
              onTap: () {
                showImagePickerDialog();
              },
            ),
          ),
        ),
      ),
    );
  }

  Future<void> showImagePickerDialog() async {
    await showDialog(
      context: context,
      builder: (BuildContext context) => Dialog(
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12.0)),
        child: Container(
          height: 200.0,
          width: 200.0,
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Padding(
                padding: EdgeInsets.all(15.0),
                child: Text(
                  "选择图片来源",
                  style: TextStyle(color: Colors.red),
                ),
              ),
              SizedBox(height: 50.0),
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceAround,
                children: [
                  ElevatedButton(
                    onPressed: () {
                      Navigator.of(context).pop();
                      openImagePicker(ImageSource.camera);
                    },
                    child: Text("相机"),
                  ),
                  ElevatedButton(
                    onPressed: () {
                      Navigator.of(context).pop();
                      openImagePicker(ImageSource.gallery);
                    },
                    child: Text("相册"),
                  ),
                  ElevatedButton(
                    onPressed: () {
                      Navigator.of(context).pop();
                    },
                    child: Text("取消"),
                  ),
                ],
              ),
            ],
          ),
        ),
      ),
    );
  }

  void openImagePicker(ImageSource source) async {
    final pickedFile = await ImagePicker().pickImage(source: source, maxWidth: 1920, maxHeight: 1920);
    if (pickedFile != null) {
      Uint8List? bytes = await pickedFile.readAsBytes();
      if (bytes != null) {
        showLoader();
        final croppedBytes = await ImageCropping.cropImage(
          context: context,
          imageBytes: bytes,
          onImageStartLoading: showLoader,
          onImageEndLoading: hideLoader,
          onImageDoneListener: (data) {
            setState(() {
              imageBytes = data;
            });
          },
          selectedImageRatio: ImageRatio.RATIO_1_1,
          visibleOtherAspectRatios: true,
          squareBorderWidth: 2,
          squareCircleColor: Colors.red,
          defaultTextColor: Colors.black,
          selectedTextColor: Colors.orange,
          colorForWhiteSpace: Colors.grey,
          encodingQuality: 80,
          outputImageFormat: OutputImageFormat.jpg,
        );
        hideLoader();
      }
    }
  }

  void showLoader() {
    if (!EasyLoading.isShow) {
      EasyLoading.show(status: '加载中...');
    }
  }

  void hideLoader() {
    EasyLoading.dismiss();
  }
}

关键点解释

  • 选择图片:通过 ImagePicker 模块从相机或图库中选择图片。
  • 显示图片选择对话框:使用 showDialog 方法创建一个简单的对话框,供用户选择图片来源。
  • 裁剪图片:调用 ImageCropping.cropImage 方法进行图片裁剪,并处理裁剪后的结果。
  • 显示加载指示器:使用 flutter_easyloading 包来显示加载状态,提升用户体验。

参数说明

必需参数

  • context:用于推送新的裁剪屏幕。
  • imageBytes:图片的字节数据,用于绘制设备上的图像。
  • onImageStartLoading:当图片开始加载时触发的回调函数。
  • onImageEndLoading:当图片加载完成时触发的回调函数。
  • onImageDoneListener:当图片裁剪完成后触发的回调函数,返回裁剪后的图片字节数据。

可选参数

  • selectedImageRatio:初始化时设置的裁剪框比例,默认为 ImageRatio.FREE
  • visibleOtherAspectRatios:是否显示其他比例选项,默认为 true
  • squareBorderWidth:裁剪框边框宽度,默认为 2
  • squareCircleColor:裁剪框圆角颜色,默认为 Colors.black
  • defaultTextColor:未选中的比例文本颜色,默认为 Colors.orange
  • selectedTextColor:选中的比例文本颜色,默认为 Colors.black
  • colorForWhiteSpace:空白区域背景颜色,默认为 Colors.grey
  • encodingQuality:裁剪后图片的质量,默认为 100
  • outputImageFormat:输出图片格式,默认为 OutputImageFormat.jpg
  • workerPath:Web平台上使用的Worker路径,默认为 'worker.js'

注意事项

对于Web平台,需要将 worker.js 文件复制到项目根目录下,否则插件将无法正常工作。裁剪后的图片数据以 Uint8List 形式返回,开发者需要自行保存这些数据。

希望这篇指南能帮助你更好地理解和使用 image_cropping 插件!如果有任何问题或建议,欢迎随时联系作者或提交Issue。


更多关于Flutter图片裁剪插件image_cropping的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter图片裁剪插件image_cropping的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter项目中使用image_cropping插件来实现图片裁剪功能的代码案例。这个插件名为image_cropper,是一个非常流行的Flutter包,用于裁剪图像。

首先,你需要在pubspec.yaml文件中添加image_cropperimage_picker依赖项(因为image_cropper通常与image_picker一起使用来选择图片):

dependencies:
  flutter:
    sdk: flutter
  image_cropper: ^3.0.1  # 请检查最新版本号
  image_picker: ^0.8.4+4  # 请检查最新版本号

然后,运行flutter pub get来安装这些依赖项。

接下来,在你的Dart文件中,你可以使用以下代码来实现图片选择和裁剪功能:

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Image Cropping Example'),
        ),
        body: Center(
          child: MyHomePage(),
        ),
      ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  File? _imageFile;

  Future<void> _pickImage() async {
    final picker = ImagePicker();
    final pickedFile = await picker.pickImage(source: ImageSource.gallery);

    if (pickedFile != null) {
      File? croppedFile = await ImageCropper().cropImage(
        sourcePath: pickedFile.path,
        aspectRatioPresets: [
          CropAspectRatioPreset.square,
          CropAspectRatioPreset.ratio3x2,
          CropAspectRatioPreset.original,
          CropAspectRatioPreset.ratio4x3,
          CropAspectRatioPreset.ratio16x9
        ],
        androidUiSettings: AndroidUiSettings(
          toolbarTitle: 'Cropper',
          toolbarColor: Colors.deepOrange,
          toolbarWidgetColor: Colors.white,
          initAspectRatio: CropAspectRatioPreset.original,
          lockAspectRatio: false,
        ),
        iosUiSettings: IOSUiSettings(
          minimumAspectRatio: 1.0,
        ),
      );

      setState(() {
        if (croppedFile != null) {
          _imageFile = croppedFile;
        }
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        ElevatedButton(
          onPressed: _pickImage,
          child: Text('Pick and Crop Image'),
        ),
        SizedBox(height: 20),
        if (_imageFile != null)
          Image.file(
            _imageFile!,
            width: 300,
            height: 300,
            fit: BoxFit.cover,
          ),
      ],
    );
  }
}

在这个示例中:

  1. 我们首先导入了必要的包。
  2. MyApp是我们的主应用程序类,它包含一个Scaffold和一个Center组件,其中包含一个MyHomePage组件。
  3. MyHomePage是一个有状态的组件,它包含一个_imageFile变量来存储选中的和裁剪后的图片。
  4. _pickImage方法使用ImagePicker从图库中选择图片,然后使用ImageCropper对图片进行裁剪。
  5. 在裁剪完成后,我们将裁剪后的图片保存到_imageFile变量中,并使用setState来刷新UI。
  6. 在UI中,我们有一个按钮用于触发图片选择和裁剪操作,并在图片被裁剪后显示裁剪后的图片。

确保你已经正确配置了Android和iOS的权限设置,以便能够从图库中选择图片。在Android上,你需要在AndroidManifest.xml中添加读写存储权限。在iOS上,你需要在Info.plist中添加相应的权限描述。

回到顶部