如何从图像选择器中裁剪图像?

Posted

技术标签:

【中文标题】如何从图像选择器中裁剪图像?【英文标题】:How to crop Image from image picker in flutter? 【发布时间】:2018-10-24 20:45:37 【问题描述】:

我想允许用户裁剪他从图像选择器中选择的图像并保存(类似于在 Whatsapp 上上传个人资料图片)。我如何在颤振中做到这一点?

示例图片:

【问题讨论】:

另见***.com/questions/44665720/… 【参考方案1】:

你可以使用这2个flutter库来实现这个,

    图像选择器; image_cropper

图像选择器使用 iosandroid 中的原生库来实现,因此它会提供良好的性能方式。

这是 image_picker 中可用的示例:

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

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

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

class ConfigScreen extends StatelessWidget 
  @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(this.title);

  @override
  _MyHomePageState createState() => _MyHomePageState();


enum AppState 
  free,
  picked,
  cropped,


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

  @override
  void initState() 
    super.initState();
    state = AppState.free;
  

  @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<Null> _pickImage() async 
    imageFile = await ImagePicker.pickImage(source: ImageSource.gallery);
    if (imageFile != null) 
      setState(() 
        state = AppState.picked;
      );
    
  

  Future<Null> _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;
    );
  

【讨论】:

请告诉我为什么使用状态。你能解释一下吗?感谢您的建议 嗨@AjayKumar,关于状态的基本原理在许多响应式前端框架中是相同的。基本上,当调用 setState() 时,组件会在屏幕上更新。在特定情况下,ImagePicker 和 ImageCropper 是外部本地库,因此需要更新整个状态。 感谢您的友好回复。你的解释让我明白了。谢谢 @AjayKumar 我很高兴知道! 你好,如何在iOS上裁剪时锁定宽高比正方形?【参考方案2】:

image_picker 已经可以裁剪图像。您为想要的图像传入指定的宽度和高度,插件实际上会裁剪原始图像。

_imageFile = ImagePicker.pickImage(source: source, maxWidth: 200.0, maxHeight: 300.0);

您要求的是另一个插件,用于在选择一个图像后裁剪图像,这将超出 image_picker 的范围。

我面临着类似的情况,您始终可以让用户使用内置的相机应用编辑照片或视频,直到有一个用于裁剪图像的插件。

要在 UI 级别裁剪图像,您可以执行以下操作: https://***.com/a/44665742/7303311

【讨论】:

不应该选择后裁剪仍然在图像选择器的范围内吗?例如,iOS 中的 Image Picker 允许裁剪... 选择图像后,您将返回文件类型。然后你可以有另一个插件来处理基于文件类型的裁剪。选择文件后,Image_picker 不再有权访问该文件。

以上是关于如何从图像选择器中裁剪图像?的主要内容,如果未能解决你的问题,请参考以下文章

如何在使用照片框架从照片中选择图像时在选择器中隐藏 iCloud 图像

如何以两种不同的大小从图像选择器中保存图像

如何从图像选择器中获取 NSData?

获取图像地理位置(从图像选择器中选择)

从图像选择器中选择的图像/视频大小(以字节为单位)

Android 图像选择器和裁剪器