Flutter图片裁剪插件image_crop_plus_updated的使用

Flutter图片裁剪插件image_crop_plus_updated的使用

image_crop_plus_updated 是一个用于在iOS和Android平台上进行图片裁剪的Flutter插件。该插件提供了一个Crop小部件,该小部件仅渲染图片、覆盖层和句柄以进行图片裁剪。因此,它可以与其他小部件组合使用,以构建自定义的图片裁剪体验。

该插件通过文件进行操作,避免通过方法通道传递大量数据。文件存储在iOS和Android的缓存文件夹中。因此,如果需要保存实际裁剪后的图片,请确保将文件复制到其他位置。

所有计算密集型工作都在主线程之外完成,通过iOS上的调度队列和Android上的缓存线程池来实现。

安装

pubspec.yaml文件中添加image_crop_plus_updated依赖项:

flutter pub add image_crop_plus_updated

使用

创建一个小部件来加载和编辑图片:

final cropKey = GlobalKey<CropState>();

Widget _buildCropImage() {
  return Container(
    color: Colors.black,
    padding: const EdgeInsets.all(20.0),
    child: Crop.file(
      imageFile, // 需要替换为实际的文件对象
      key: cropKey,
      aspectRatio: 4.0 / 3.0, // 设置宽高比
    ),
  );
}

访问裁剪值:

  • scale 是一个比例因子,用于按比例缩放裁剪后的图片宽度和高度。1.0表示不需要缩放。
  • area 是一个矩形,指示图片上要裁剪的分数位置。
final crop = cropKey.currentState;
// 或者
// final crop = Crop.of(context);
final scale = crop.scale;
final area = crop.area;

if (area == null) {
  // 无法裁剪,小部件未设置
  // ...
}

访问和处理图片。作为方便的功能,请求访问照片的权限:

final permissionsGranted = await ImageCrop.requestPermissions();

读取图片选项,例如宽度和高度。这是一种高效的实现方式,不会解码或加载实际图像到内存中。

final options = await getImageOptions(file: file);
debugPrint('image width: ${options.width}, height: ${options.height}');

如果图片太大,无法加载到内存中,可以使用采样功能,依靠原生平台按比例缩小图片,然后再加载到内存中。例如,将图像重采样为尽可能接近1024x4096的尺寸。如果是一个正方形,可以使用preferredSize指定宽度和高度。最好在显示图像时利用此功能。

final sampleFile = await ImageCrop.sampleImage(
  file: originalFile,
  preferredWidth: 1024,
  preferredHeight: 4096,
);

一旦Crop小部件准备好,就可以使用原生支持进行裁剪和缩放图像。为了生成高质量的裁剪图像,建议使用带有首选最大宽度和高度的采样图像。放大采样图像的分辨率。裁剪后,图像将以更高的分辨率存在。示例如下:

final sampledFile = await ImageCrop.sampleImage(
  file: originalFile,
  preferredWidth: (1024 / crop.scale).round(),
  preferredHeight: (4096 / crop.scale).round(),
);

final croppedFile = await ImageCrop.cropImage(
  file: sampledFile,
  area: crop.area,
);

示例代码

以下是一个完整的示例代码,展示了如何使用image_crop_plus_updated插件来裁剪图片:

import 'dart:io';
import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:image_crop_plus_updated/image_crop_plus_updated.dart';
import 'package:image_picker/image_picker.dart';

void main() {
  SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
    statusBarColor: Colors.transparent,
    statusBarBrightness: Brightness.dark,
    statusBarIconBrightness: Brightness.light,
    systemNavigationBarIconBrightness: Brightness.light,
  ));

  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  [@override](/user/override)
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final cropKey = GlobalKey<CropState>();
  File? _file;
  File? _sample;
  File? _lastCropped;

  [@override](/user/override)
  void dispose() {
    super.dispose();
    _file?.delete();
    _sample?.delete();
    _lastCropped?.delete();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: SafeArea(
        child: Container(
          color: Colors.black,
          padding: const EdgeInsets.symmetric(vertical: 40.0, horizontal: 20.0),
          child: _sample == null ? _buildOpeningImage() : _buildCroppingImage(),
        ),
      ),
    );
  }

  Widget _buildOpeningImage() {
    return Center(child: _buildOpenImage());
  }

  Widget _buildCroppingImage() {
    return Column(
      children: <Widget>[
        Expanded(
          child: Crop.file(
            _sample!,
            key: cropKey,
          ),
        ),
        Container(
          padding: const EdgeInsets.only(top: 20.0),
          alignment: AlignmentDirectional.center,
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: <Widget>[
              TextButton(
                child: Text(
                  'Crop Image',
                  style: Theme.of(context)
                      .textTheme
                      .labelLarge!
                      .copyWith(color: Colors.white),
                ),
                onPressed: () => _cropImage(),
              ),
              _buildOpenImage(),
            ],
          ),
        )
      ],
    );
  }

  Widget _buildOpenImage() {
    return TextButton(
      child: Text(
        'Open Image',
        style: Theme.of(context)
            .textTheme
            .labelLarge!
            .copyWith(color: Colors.white),
      ),
      onPressed: () => _openImage(),
    );
  }

  Future<void> _openImage() async {
    final pickedFile = await ImagePicker().getImage(source: ImageSource.gallery);
    final file = File(pickedFile!.path);
    print(file);
    final sample = await ImageCrop.sampleImage(
      file: file,
      preferredSize: context.size!.longestSide.toInt() * 2,
    );

    if (_sample != null) _sample!.delete();
    if (_file != null) _file!.delete();

    setState(() {
      _sample = sample;
      _file = file;
    });
  }

  Future<void> _cropImage() async {
    final scale = cropKey.currentState!.scale;
    final area = cropKey.currentState!.area;
    if (area == null) {
      // 无法裁剪,小部件未设置
      return;
    }

    // 按比例缩放以使用尽可能多的像素
    // 这将在更高分辨率下采样图像,以便裁剪图像更大
    final sample = await ImageCrop.sampleImage(
      file: _file!,
      preferredSize: (2000 / scale).round(),
    );

    final file = await ImageCrop.cropImage(
      file: sample,
      area: area,
    );

    sample.delete();

    _lastCropped?.delete();
    _lastCropped = file;

    debugPrint('$file');
  }
}

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

1 回复

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


image_crop_plus_updated 是一个用于 Flutter 的图片裁剪插件,它允许用户从图库中选择图片并进行裁剪。以下是使用该插件的基本步骤:

1. 添加依赖

首先,在 pubspec.yaml 文件中添加 image_crop_plus_updated 插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  image_crop_plus_updated: ^1.0.0  # 请使用最新版本

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

2. 配置权限

AndroidManifest.xmlInfo.plist 文件中添加必要的权限,以便访问设备的图库和摄像头。

Android (AndroidManifest.xml):

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CAMERA"/>

iOS (Info.plist):

<key>NSPhotoLibraryUsageDescription</key>
<string>我们需要访问您的相册以选择图片</string>
<key>NSCameraUsageDescription</key>
<string>我们需要访问您的相机以拍摄图片</string>

3. 使用插件进行图片裁剪

3.1 导入插件

import 'package:image_crop_plus_updated/image_crop_plus_updated.dart';

3.2 选择图片并进行裁剪

Future<void> cropImage() async {
  // 选择图片
  final pickedFile = await ImagePicker().getImage(source: ImageSource.gallery);

  if (pickedFile != null) {
    // 初始化裁剪器
    final croppedFile = await ImageCrop.cropImage(
      file: File(pickedFile.path),
      aspectRatio: CropAspectRatio(ratioX: 1.0, ratioY: 1.0), // 设置裁剪框的宽高比
    );

    // 获取裁剪后的图片文件
    if (croppedFile != null) {
      // 处理裁剪后的图片
      final croppedImage = File(croppedFile.path);
      // 例如,显示裁剪后的图片
      setState(() {
        _image = croppedImage;
      });
    }
  }
}

3.3 显示裁剪后的图片

class MyApp extends StatefulWidget {
  [@override](/user/override)
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  File? _image;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Image Crop Example'),
      ),
      body: Center(
        child: _image == null
            ? Text('No image selected.')
            : Image.file(_image!),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: cropImage,
        tooltip: 'Crop Image',
        child: Icon(Icons.crop),
      ),
    );
  }
}
回到顶部