今回は、トリミングなど画像加工を簡単に行えるimage_cropperを使ってみたいと思います。
次のコマンドを使用し、パッケージをインストールします。
$ flutter pub add image_cropper
pubspec.yamlに以下が追加されていればOKです。
dependencies: image_cropper: ^1.5.1
Androidで動かす場合、AndroidManifest.xmlに以下の追加が必要になります。
<activity android:name="com.yalantis.ucrop.UCropActivity" android:screenOrientation="portrait" android:theme="@style/Theme.AppCompat.Light.NoActionBar"/>
また、本サンプルではトリミングする画像を端末から取得するために、パッケージのimage_pickerを使用します。
$ flutter pub add image_picker
こちらもpubspec.yamlに以下が追加されます。
dependencies: image_picker: ^0.8.5
また、image_pickerをiOSで使用する際は、端末の画像にアクセスするためNSPhotoLibraryUsageDescriptionを付与してください。
<key>NSPhotoLibraryUsageDescription</key> <string></string>
サンプルのコードは以下になります。
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 MyApp()); class MyApp 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({required this.title}); @override _MyHomePageState createState() => _MyHomePageState(); } enum AppState { free, picked, cropped, } class _MyHomePageState extends State<MyHomePage> { late 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 { final pickedImage = await ImagePicker().pickImage(source: ImageSource.gallery); imageFile = pickedImage != null ? File(pickedImage.path) : null; 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; }); } }
image_cropperが画像の編集画面を用意しており、
画像の回転や
範囲を選択して切り抜きをこなうことができます。
また、切り抜く範囲の比率もある程度選択でき、例えばSquareを選択すると、切り抜き範囲が正方形になります。
かなり簡単に使える上に、viewも用意してくれていてかなり優秀なパッケージだと思いました。プロフィールのアイコンなど画像設定するような機能を実装する際にはお供にしても良いかと思います。