Flutter图片裁剪插件sparrow_image_cropper的使用

Flutter图片裁剪插件sparrow_image_cropper的使用

Sparrow Image Cropper 是一个用于Android和iOS平台的Flutter插件,支持图片裁剪功能。该插件基于两个不同的原生库(uCropTOCropViewController),因此在不同平台上具有不同的用户界面。

介绍

Image Cropper 不直接在Dart代码中处理图像,而是通过平台通道(Platform Channels)暴露给Flutter应用可以使用的API,以与两个非常强大的原生库(uCropTOCropViewController)通信来裁剪和旋转图像。因此,所有功劳归于这些库。

uCrop - Yalantis
TOCropViewController - TimOliver

如何安装

Android
  1. UCropActivity 添加到你的 AndroidManifest.xml 文件中:
<activity
    android:name="com.yalantis.ucrop.UCropActivity"
    android:screenOrientation="portrait"
    android:theme="@style/Theme.AppCompat.Light.NoActionBar"/>

注意:

从v1.2.0版本开始,你需要将你的Android项目迁移到v2嵌入(详情见这里)。

iOS

无需配置。

使用方法

必须参数
  • sourcePath: 图像文件的绝对路径。
可选参数
  • maxWidth: 裁剪后图像的最大宽度。
  • maxHeight: 裁剪后图像的最大高度。
  • aspectRatio: 控制裁剪边界的比例。如果设置此值,则裁剪器会被锁定,用户无法更改裁剪边界的比例。
  • aspectRatioPresets: 控制裁剪菜单视图中的比例列表。在Android上,可以通过设置 AndroidUiSettings.initAspectRatio 的值来初始化裁剪时的比例。
  • cropStyle: 控制裁剪边框的样式,可以是矩形或圆形(默认为 CropStyle.rectangle)。
  • compressFormat: 结果图像的格式,可以是png或jpg(默认为 ImageCompressFormat.jpg)。
  • compressQuality: 控制图像压缩质量的值 [0 - 100]。
  • androidUiSettings: 控制Android上的UI自定义。详见Android自定义
  • iosUiSettings: 控制iOS上的UI自定义。详见iOS自定义

注意:

结果文件保存在iOS的 NSTemporaryDirectory 和Android的应用程序缓存目录中,因此可能会丢失。如果你需要永久保存,需要自己负责存储。

自定义

Android

Image Cropper 提供了一个名为 AndroidUiSettings 的辅助类,该类封装了可以在 uCrop 库中自定义UI的所有属性。

属性名称 描述 类型
toolbarTitle 想要的工具栏标题文本 字符串
toolbarColor 工具栏的颜色 颜色
statusBarColor 状态栏的颜色 颜色
toolbarWidgetColor 工具栏文本和按钮的颜色(默认是更深的橙色) 颜色
backgroundColor 应用到根视图的背景颜色 颜色
activeControlsWidgetColor 活动和选定小部件及进度轮中间线的颜色(默认是白色) 颜色
dimmedLayerColor 裁剪边界周围的暗化区域的颜色 颜色
cropFrameColor 裁剪边框的颜色 颜色
cropGridColor 裁剪网格/指导线的颜色 颜色
cropFrameStrokeWidth 裁剪边框线的宽度(像素) 整数
cropGridRowCount 裁剪网格行数 整数
cropGridColumnCount 裁剪网格列数 整数
cropGridStrokeWidth 裁剪网格线的宽度(像素) 整数
showCropGrid 如果为真,则会在图像顶部显示裁剪网格/指导线 布尔值
lockAspectRatio 如果为真,则锁定裁剪边界的固定比例(默认锁定) 布尔值
hideBottomControls 如果为真,则隐藏底部控件(默认显示) 布尔值
initAspectRatio 开始裁剪时应用的所需比例(来自给定的比例预设列表) CropAspectRatioPreset
iOS

Image Cropper 提供了一个名为 IOSUiSettings 的辅助类,该类封装了可以在 TOCropViewController 库中自定义UI的所有属性。

属性名称 描述 类型
minimumAspectRatio 最小裁剪比例。如果设置,用户将被阻止设置低于此参数定义的裁剪矩形比例 浮点数
rectX 初始裁剪矩形的x坐标 浮点数
rectY 初始裁剪矩形的y坐标 浮点数
rectWidth 初始裁剪矩形的宽度 浮点数
rectHeight 初始裁剪矩形的高度 浮点数
showActivitySheetOnDone 如果为真,在用户点击“完成”后,会先出现一个 UIActivityController,然后再结束视图控制器 布尔值
showCancelConfirmationDialog 当用户点击“取消”且有未保存更改时,显示确认对话框(默认为假) 布尔值
rotateClockwiseButtonHidden 如果禁用,则在工具栏中显示一个额外的旋转按钮,可以按90度顺时针方向旋转画布(默认为假) 布尔值
hidesNavigationBar 如果控制器嵌入在 UINavigationController 中,默认隐藏导航栏。设置为假以显示导航栏。必须在控制器展示之前设置 布尔值
rotateButtonsHidden 如果启用,隐藏旋转按钮以及当 showClockwiseRotationButton 设置为YES时可见的替代旋转按钮(默认为假) 布尔值
resetButtonHidden 如果启用,隐藏工具栏中的“重置”按钮(默认为假) 布尔值
aspectRatioPickerButtonHidden 如果启用,隐藏工具栏中的“比例选择”按钮(默认为假) 布尔值
resetAspectRatioEnabled 如果为真,点击重置按钮也将把比例重置回图像的原始比例。否则,重置只会缩放到当前比例。如果设置为假,并且 aspectRatioLockEnabled 为真,则比例按钮将自动从工具栏中隐藏(默认为真) 布尔值
aspectRatioLockDimensionSwapEnabled 如果为真,设置了自定义比例,并且 aspectRatioLockEnabled 为真,则裁剪框将根据横向或纵向的图像尺寸交换其尺寸。此值还控制当图像旋转时是否可以交换尺寸(默认为假) 布尔值
aspectRatioLockEnabled 如果为真,虽然仍然可以调整大小,但裁剪框将锁定在其当前比例。如果设置为真,并且 resetAspectRatioEnabled 为假,则比例按钮将自动从工具栏中隐藏(默认为假) 布尔值
title 视图控制器顶部显示的标题文本 字符串
doneButtonTitle “完成”按钮的标题。设置此值将覆盖默认的本地化字符串“完成” 字符串
cancelButtonTitle “取消”按钮的标题。设置此值将覆盖默认的本地化字符串“取消” 字符串

示例

以下是一个完整的示例,展示了如何使用 sparrow_image_cropper 插件进行图片裁剪。

import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:io';

import 'package:sparrow_image_cropper/sparrow_image_cropper.dart';
import 'package:sparrow_image_picker/sparrow_image_picker.dart';

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

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'ImageCropper',
      theme: ThemeData.light().copyWith(primaryColor: Colors.deepOrange),
      home: MyHomePage(
        title: 'ImageCropper',
      ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  final String title;

  MyHomePage({required this.title});

  [@override](/user/override)
  _MyHomePageState createState() => _MyHomePageState();
}

enum AppState {
  free,
  picked,
  cropped,
}

class _MyHomePageState extends State<MyHomePage> {
  late AppState state;
  File? imageFile;

  [@override](/user/override)
  void initState() {
    super.initState();
    state = AppState.free;
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: imageFile != null ? Image.file(imageFile!) : Container(),
      ),
      floatingActionButton: FloatingActionButton(
        backgroundColor: Colors.deepOrange,
        onPressed: () {
          if (state == AppState.free)
            _pickImage();
          else if (state == AppState.picked)
            _cropImage();
          else if (state == AppState.cropped) _clearImage();
        },
        child: _buildButtonIcon(),
      ),
    );
  }

  Widget _buildButtonIcon() {
    if (state == AppState.free)
      return Icon(Icons.add);
    else if (state == AppState.picked)
      return Icon(Icons.crop);
    else if (state == AppState.cropped)
      return Icon(Icons.clear);
    else
      return Container();
  }

  Future<void> _pickImage() async {
    final pickedImage = await ImagePicker().pickImage(source: ImageSource.gallery);
    imageFile = pickedImage != null ? File(pickedImage.path) : null;
    if (imageFile != null) {
      setState(() {
        state = AppState.picked;
      });
    }
  }

  Future<void> _cropImage() async {
    File? croppedFile = await ImageCropper.cropImage(
        sourcePath: imageFile!.path,
        aspectRatioPresets: Platform.isAndroid
            ? [
                CropAspectRatioPreset.square,
                CropAspectRatioPreset.ratio3x2,
                CropAspectRatioPreset.original,
                CropAspectRatioPreset.ratio4x3,
                CropAspectRatioPreset.ratio16x9
              ]
            : [
                CropAspectRatioPreset.original,
                CropAspectRatioPreset.square,
                CropAspectRatioPreset.ratio3x2,
                CropAspectRatioPreset.ratio4x3,
                CropAspectRatioPreset.ratio5x3,
                CropAspectRatioPreset.ratio5x4,
                CropAspectRatioPreset.ratio7x5,
                CropAspectRatioPreset.ratio16x9
              ],
        androidUiSettings: AndroidUiSettings(
            toolbarTitle: 'Cropper',
            toolbarColor: Colors.deepOrange,
            toolbarWidgetColor: Colors.white,
            initAspectRatio: CropAspectRatioPreset.original,
            lockAspectRatio: false),
        iosUiSettings: IOSUiSettings(
          title: 'Cropper',
        ));
    if (croppedFile != null) {
      imageFile = croppedFile;
      setState(() {
        state = AppState.cropped;
      });
    }
  }

  void _clearImage() {
    imageFile = null;
    setState(() {
      state = AppState.free;
    });
  }
}

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

1 回复

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


当然,下面是一个关于如何使用Flutter中的sparrow_image_cropper插件进行图片裁剪的代码示例。这个插件允许用户在Flutter应用中裁剪图像。

步骤1:添加依赖

首先,你需要在pubspec.yaml文件中添加sparrow_image_cropper的依赖:

dependencies:
  flutter:
    sdk: flutter
  sparrow_image_cropper: ^x.y.z  # 替换为最新版本号

然后运行flutter pub get来安装依赖。

步骤2:导入插件

在你的Dart文件中导入sparrow_image_cropper插件:

import 'package:sparrow_image_cropper/sparrow_image_cropper.dart';

步骤3:使用插件

下面是一个完整的示例,展示如何使用sparrow_image_cropper进行图片裁剪:

import 'package:flutter/material.dart';
import 'package:sparrow_image_cropper/sparrow_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 Cropper Example'),
        ),
        body: ImageCropperPage(),
      ),
    );
  }
}

class ImageCropperPage extends StatefulWidget {
  @override
  _ImageCropperPageState createState() => _ImageCropperPageState();
}

class _ImageCropperPageState extends State<ImageCropperPage> {
  File? _imageFile;
  CroppedFile? _croppedFile;

  final ImagePicker _picker = ImagePicker();

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

    if (pickedFile != null) {
      setState(() {
        _imageFile = File(pickedFile.path);
      });

      // 打开裁剪页面
      _cropImage();
    }
  }

  Future<void> _cropImage() async {
    if (_imageFile == null) return;

    final croppedFile = await SparrowImageCropper.cropImage(
      sourcePath: _imageFile!.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) return;
      _croppedFile = croppedFile;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(16.0),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          Text('Original Image:'),
          _imageFile == null
              ? Text('No image selected.')
              : Image.file(_imageFile!, width: 300, fit: BoxFit.cover),
          SizedBox(height: 20),
          Text('Cropped Image:'),
          _croppedFile == null
              ? Text('No cropped image available.')
              : Image.file(_croppedFile!.path, width: 300, fit: BoxFit.cover),
          SizedBox(height: 20),
          ElevatedButton(
            onPressed: _pickImage,
            child: Text('Pick Image'),
          ),
        ],
      ),
    );
  }
}

注意事项

  1. 权限处理:确保在Android和iOS平台上请求必要的存储权限。
  2. 依赖冲突:如果与其他图像选择或裁剪插件有冲突,请检查依赖版本和兼容性。
  3. 错误处理:添加适当的错误处理,例如用户取消选择图像或裁剪操作失败时的处理。

这个示例展示了如何从图库中选择图像,并使用sparrow_image_cropper进行裁剪,然后显示原始图像和裁剪后的图像。希望这个示例对你有所帮助!

回到顶部