I want to allow the user to crop the Image he chose from the image picker and save it(Similar to uploading profile pic on Whatsapp). How can I do this in flutter?
Sample Image:
I want to allow the user to crop the Image he chose from the image picker and save it(Similar to uploading profile pic on Whatsapp). How can I do this in flutter?
Sample Image:
You can use these 2 flutter libraries to achieve this,
The image picker use the native libraries in iOS and Android to achieve it, therefore it will delivery a good performance way.
Here is a sample available in 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;
});
}
}
The image_picker already can crop the image. You pass in the specified width and height for the image you want and the plugin actually crops the original image.
_imageFile = ImagePicker.pickImage(source: source, maxWidth: 200.0, maxHeight: 300.0);
What you are asking for is another plugin to crop images after one has been selected and that would be outside the scope of the image_picker.
I am facing something similar and you can always have the user edit the photo or video with the built in camera app until there is a plugin made for cropping images.
For cropping images on the UI level you can do something like this: https://stackoverflow.com/a/44665742/7303311
To crop the image from image_cropper library you case just set the
aspectRatio: CropAspectRatio(ratioX: 1, ratioY: 1)
Here's the sample code:
CroppedFile? croppedFile = await ImageCropper().cropImage(
sourcePath: pickedImage.path,
aspectRatio: imagePickingType == ImagePickingType.profilePic ? CropAspectRatio(ratioX: 1, ratioY: 1) :
imagePickingType == ImagePickingType.communityWall ? CropAspectRatio(ratioX: 16, ratioY: 9) : null,
uiSettings: [
AndroidUiSettings(
toolbarTitle: cropPageTitle ?? 'Edit Image',
toolbarColor: toolbarTextColor ??
theme.scaffoldBackgroundColor,
toolbarWidgetColor: toolbarBackgroundColor ??
theme.primaryColor,
initAspectRatio:
initialAspectRation ?? CropAspectRatioPreset.original,
lockAspectRatio: (imagePickingType == ImagePickingType.profilePic) || (imagePickingType == ImagePickingType.communityWall),
backgroundColor: theme.scaffoldBackgroundColor,
activeControlsWidgetColor: theme.primaryColor,
),
IOSUiSettings(
title: cropPageTitle ?? 'Edit Image',
rotateClockwiseButtonHidden: true,
aspectRatioPickerButtonHidden: true,
aspectRatioLockEnabled: (imagePickingType == ImagePickingType.profilePic) || (imagePickingType == ImagePickingType.communityWall),
rotateButtonsHidden: true,
),
],
);
if (croppedFile != null) {
return File(croppedFile.path);
} else {
File(pickedImage.path);
}