Image Compress & Crop In Flutter
Working with the camera/gallery and involving it in various applications is very typical in applications yet while carrying out it you might deal with different issues -, for example, assuming you are working in an application that is fundamentally an e-commerce application where we really want to oversee various things we want to choose various things and furthermore post our reactions with pictures around then we should have to compose a single codebase from where we can oversee camera at various areas all through the application.
In this article, we will explore the Image Compress & Crop In Flutter. We will see how to implement a demo program. Learn how to image compress and crop using a camera & gallery in your flutter applications.
For Image Compress:
flutter_native_image | Flutter Package
Run this command: With Flutter: $ flutter pub add flutter_native_image This will add a line like this to your package’s…pub.dev
For Image Crop:
image_cropper | Flutter Package
A Flutter plugin for Android, iOS, and Web supports cropping images. This plugin is based on three different native… pubs.dev
For Image Picker:
image_picker | Flutter Package
A Flutter plugin for iOS and Android for picking images from the image library, and taking new pictures with the…pub.dev
Table Of Contents::
Introduction:
The below demo video shows how to implement an image compress & crop in flutter and shows how image compress & crop will work using the camera and gallery in your flutter applications. We will show a user when clicking on the upload button and then, show a popup with a camera and gallery fields. When the user chooses any one option then the image will be compressed and then crop and It will be shown on your device.
Demo Module ::
Implementation:
Step 1: Add the dependencies
Add dependencies to pubspec — yaml file.
dependencies:
flutter:
sdk: flutter
image_picker: ^0.8.5
image_cropper: ^1.5.1
flutter_native_image: ^0.0.6+1
Step 2: Import
import 'package:image_picker/image_picker.dart';
import 'package:flutter_native_image/flutter_native_image.dart';
import 'package:image_cropper/image_cropper.dart'
Step 3: Add a few things to the AndriodManifest.xml file.
<activity
android:name="com.yalantis.ucrop.UCropActivity"
android:screenOrientation="portrait"
android:theme="@style/Theme.AppCompat.Light.NoActionBar"/>
Step 4: Run flutter packages get in the root directory of your app.
How to implement code in dart file :
You need to implement it in your code respectively:
Create a new dart file called app_helper.dart
inside the lib
folder.
We will create an AppHelper() class. In this class, we will create the static cropImage name file and add all data for the crop images. Yow will use it anywhere in our project.
static Future<File?> cropImage(File? imageFile) async {
var _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: const AndroidUiSettings(
toolbarColor: Color(0xFF2564AF),
toolbarWidgetColor: Colors.white,
initAspectRatio: CropAspectRatioPreset.original,
lockAspectRatio: false),
);
return _croppedFile;
}
Also, we will create a static compress name file, and inside we will add a file image, quality, and percentage of an image. Yow will use it anywhere in our project.
static Future<File> compress({
required File image,
int quality = 100,
int percentage = 30,
}) async {
var path = await FlutterNativeImage.compressImage(image.absolute.path,
quality: quality, percentage: percentage);
return path;
}
}
Create a new dart file called home_page.dart
inside the lib
folder.
First, we will create a final _picker that is equal to the ImagePicker(). Also, creating a File instance was fileImage.
final _picker = ImagePicker();
File? fileImage;
In the body, we will add the column. In this column widget, we will add a Container with height and width. Inside the Container, we will add a Column widget. In this widget, we will add images and text. When the user run code then shows this screen before adding any image.
Container(
height: 350,
width: 350,
alignment: Alignment.center,
decoration: BoxDecoration(
border: Border.all(color: Colors.black12, width: 1),
borderRadius: const BorderRadius.all(Radius.circular(10)),
color: Colors.grey[300],
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
"assets/logo.png",
width: 150,
),
const SizedBox(
height: 20,
),
const Text(
"Image will be shown here",
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.w700,
fontSize: 20),
),
],
),
),
Also, create a ElevatedButton(). On this button, we will add the onPressed method. In this method, we will add _openChangeImageBottomSheet() function. This function we will describe later below. Also, add the text ‘Upload Image’.
ElevatedButton(
onPressed: () {
_openChangeImageBottomSheet();
},
child: const Text('Upload Image')),
When we run the application, we ought to get the screen’s output like the underneath screen capture.
We will add create a container with height and width, alignment was center. Add the box decoration with border color, border-radius , color and DecorationImage(). Inside DecorationImage, we will add an image: FileImage(fileImage!). When a user uploads an image using compresses and crops an image from the camera and gallery.
Container(
height: 350,
width: 300,
alignment: Alignment.center,
decoration: BoxDecoration(
border: Border.all(color: Colors.black12, width: 1),
borderRadius: const BorderRadius.all(Radius.circular(10)),
color: Colors.grey,
image: DecorationImage(
image: FileImage(fileImage!),
fit: BoxFit.cover,
)),
)
When we run the application, we ought to get the screen’s output like the underneath screen capture.
Now, we will describe _openChangeImageBottomSheet() function:
We will create a showCupertinoModalPopup(). In this popup, we will return CupertinoActionSheet(). In this sheet, we will add the actions widget. In actions widget, we will add three _buildCupertinoActionSheetAction(). Inside we will add icons, titles, and the voidCallback function. In this function, we will add Navigator.pop(context) and _getImageFrom(source: ImageSource.gallery/camera). We will define the below later.
_openChangeImageBottomSheet() {
return showCupertinoModalPopup(
context: context,
barrierDismissible: false,
builder: (context) {
return CupertinoActionSheet(
title: Text(
'Change Image',
textAlign: TextAlign.center,
style: AppTextStyles.regular(fontSize: 19),
),
actions: <Widget>[
_buildCupertinoActionSheetAction(
icon: Icons.camera_alt,
title: 'Take Photo',
voidCallback: () {
Navigator.pop(context);
_getImageFrom(source: ImageSource.camera);
},
),
_buildCupertinoActionSheetAction(
icon: Icons.image,
title: 'Gallery',
voidCallback: () {
Navigator.pop(context);
_getImageFrom(source: ImageSource.gallery);
},
),
_buildCupertinoActionSheetAction(
title: 'Cancel',
color: Colors.red,
voidCallback: () {
Navigator.pop(context);
},
),
],
);
});
}
We will define _buildCupertinoActionSheetAction() function.
In this function, we will add IconData, title, and voidCallback. We will return a CupertinoActionSheetAction(). In this sheet, we will add a Row widget. In this widget, we will add an icon, title, and onPressed.
_buildCupertinoActionSheetAction({
IconData? icon,
required String title,
required VoidCallback voidCallback,
Color? color,
}) {
return CupertinoActionSheetAction(
child: Row(
children: [
if (icon != null)
Icon(
icon,
color: color ?? const Color(0xFF2564AF),
),
Expanded(
child: Text(
title,
textAlign: TextAlign.center,
style: AppTextStyles.regular(
fontSize: 17,
color: color ?? const Color(0xFF2564AF),
),
),
),
if (icon != null)
const SizedBox(
width: 25,
),
],
),
onPressed: voidCallback,
);
}
When we run the application, we ought to get the screen’s output like the underneath screen capture.
Now, we will describe _getImageFrom({required ImageSource source}) function:
This is the main function, when the user clicks on the popup button and then pressed the camera /gallery button, then first shows pic the original size of the image and then shows after compressed image size.
When we run the application, we ought to get the screen’s output like the underneath screen capture.
When we run the application, we ought to get the console output like the underneath.
I/flutter ( 8840): Before Compress 4750.7578125 kb
I/flutter ( 8840): After Compress 1095.669921875 kb
Now, after compressing the image, then the image will be moved to the crop part. The user will crop the image and the set to the fileImage is equal to the _croppedImage. The user will crop on any ratio and also, rotate the image.
_getImageFrom({required ImageSource source}) async {
final _pickedImage = await _picker.pickImage(source: source);
if (_pickedImage != null) {
var image = File(_pickedImage.path.toString());
final _sizeInKbBefore = image.lengthSync() / 1024;
print('Before Compress $_sizeInKbBefore kb');
var _compressedImage = await AppHelper.compress(image: image);
final _sizeInKbAfter = _compressedImage.lengthSync() / 1024;
print('After Compress $_sizeInKbAfter kb');
var _croppedImage = await AppHelper.cropImage(_compressedImage);
if (_croppedImage == null) {
return;
}
setState(() {
fileImage = _croppedImage;
});
}
}
When we run the application, we ought to get the screen’s output like the underneath screen capture.
Code File:
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_image_compress_crop/app_helper.dart';
import 'package:flutter_image_compress_crop/app_text_style.dart';
import 'package:image_picker/image_picker.dart';
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final _picker = ImagePicker();
File? fileImage;
_getImageFrom({required ImageSource source}) async {
final _pickedImage = await _picker.pickImage(source: source);
if (_pickedImage != null) {
var image = File(_pickedImage.path.toString());
final _sizeInKbBefore = image.lengthSync() / 1024;
print('Before Compress $_sizeInKbBefore kb');
var _compressedImage = await AppHelper.compress(image: image);
final _sizeInKbAfter = _compressedImage.lengthSync() / 1024;
print('After Compress $_sizeInKbAfter kb');
var _croppedImage = await AppHelper.cropImage(_compressedImage);
if (_croppedImage == null) {
return;
}
setState(() {
fileImage = _croppedImage;
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Flutter Image Crop & Compress Demo "),
centerTitle: true,
automaticallyImplyLeading: false,
backgroundColor: Colors.teal,
),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
if (fileImage != null)
Container(
height: 350,
width: 300,
alignment: Alignment.center,
decoration: BoxDecoration(
border: Border.all(color: Colors.black12, width: 1),
borderRadius: const BorderRadius.all(Radius.circular(10)),
color: Colors.grey,
image: DecorationImage(
image: FileImage(fileImage!),
fit: BoxFit.cover,
)),
)
else
Container(
height: 350,
width: 350,
alignment: Alignment.center,
decoration: BoxDecoration(
border: Border.all(color: Colors.black12, width: 1),
borderRadius: const BorderRadius.all(Radius.circular(10)),
color: Colors.grey[300],
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
"assets/logo.png",
width: 150,
),
const SizedBox(
height: 20,
),
const Text(
"Image will be shown here",
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.w700,
fontSize: 20),
),
],
),
),
const SizedBox(
height: 50,
),
Center(
child: ElevatedButton(
onPressed: () {
_openChangeImageBottomSheet();
},
child: const Text('Upload Image')),
),
],
),
);
}
_openChangeImageBottomSheet() {
return showCupertinoModalPopup(
context: context,
barrierDismissible: false,
builder: (context) {
return CupertinoActionSheet(
title: Text(
'Change Image',
textAlign: TextAlign.center,
style: AppTextStyles.regular(fontSize: 19),
),
actions: <Widget>[
_buildCupertinoActionSheetAction(
icon: Icons.camera_alt,
title: 'Take Photo',
voidCallback: () {
Navigator.pop(context);
_getImageFrom(source: ImageSource.camera);
},
),
_buildCupertinoActionSheetAction(
icon: Icons.image,
title: 'Gallery',
voidCallback: () {
Navigator.pop(context);
_getImageFrom(source: ImageSource.gallery);
},
),
_buildCupertinoActionSheetAction(
title: 'Cancel',
color: Colors.red,
voidCallback: () {
Navigator.pop(context);
},
),
],
);
});
}
_buildCupertinoActionSheetAction({
IconData? icon,
required String title,
required VoidCallback voidCallback,
Color? color,
}) {
return CupertinoActionSheetAction(
child: Row(
children: [
if (icon != null)
Icon(
icon,
color: color ?? const Color(0xFF2564AF),
),
Expanded(
child: Text(
title,
textAlign: TextAlign.center,
style: AppTextStyles.regular(
fontSize: 17,
color: color ?? const Color(0xFF2564AF),
),
),
),
if (icon != null)
const SizedBox(
width: 25,
),
],
),
onPressed: voidCallback,
);
}
}
Conclusion:
In the article, I have explained the basic structure of image compress & crop in a flutter; you can modify this code according to your choice. This was a small introduction to Image Compress & Crop On User Interaction from my side, and it’s working using Flutter.
I hope this blog will provide you with sufficient information on Trying up the Image Compress & Crop in your flutter projects. We will show you what an Introduction is?. Show the implementations, and how to use Image Compress & Crop from the camera and gallery. Make a demo program for working in your flutter applications. So please try it.
❤ ❤ Thanks for reading this article ❤❤
If I got something wrong? Let me know in the comments. I would love to improve.
Clap 👏 If this article helps you.
GitHub Link:
find the source code of the Flutter Image Compress Crop Demo:
GitHub – flutter-devs/flutter_image_compress_crop_demo
A new Flutter project. This project is a starting point for a Flutter application. A few resources to get you started…github.com
Feel free to connect with us:
And read more articles from FlutterDevs.com.
FlutterDevs team of Flutter developers to build high-quality and functionally-rich apps. Hire a flutter developer for your cross-platform Flutter mobile app project on an hourly or full-time basis as per your requirement! You can connect with us on Facebook, GitHub, Twitter, and LinkedIn for any flutter-related queries.
We welcome feedback and hope that you share what you’re working on using #FlutterDevs. We truly enjoy seeing how you use Flutter to build beautiful, interactive web experiences.