Photo Editing Application in Flutter
Last Updated :
09 Apr, 2025
With the introduction of the powerful image_editor_plus package, editing images directly within your Flutter app has become significantly more accessible. In this article, we’ll dive deep into building a user-friendly image editor app. Users will have the ability to select an image from their camera or gallery, allowing for versatility based on their preferences. Once an image is chosen, they can utilize the built-in UI to explore a range of editing features, such as cropping, adjusting brightness, applying filters, and more. Finally, users will be able to preview and save their edited images, providing a complete and satisfying experience from start to finish.
Steps to Create a Photo-Editing Application in Flutter
Step 1 : Create a New Flutter Application
Create a new Flutter application using the command Prompt. To create a new app, write the below command and run it.
flutter create app_name
To know more about it refer this article: Creating a Simple Application in Flutter
Step 2 : Adding the Dependency
Packages Used: We’re using the following Flutter packages:
Package
| Purpose
|
---|
image_picker
| To pick images from the camera or gallery
|
---|
image_editor_plus
| Provides a full-featured editor UI
|
---|
path_provider
| To save edited images in a temporary folder
|
---|
permission_handler
| Handles runtime permissions
|
---|
To add the dependency to the pubspec.yaml file, add image_picker, image_editor_plus, path_provider, and permission_handler as a dependency in the dependencies part of the pubspec.yaml file, as shown below:
Dart
dependencies:
flutter:
sdk: flutter
image_editor_plus: ^1.0.6
image_picker: ^1.1.2
path_provider: ^2.1.5
permission_handler: ^11.4.0
Now run the below command in the terminal.
flutter pub get
Or
Run the below command in the terminal.
flutter pub add image_picker image_editor_plus path_provider permission_handler
Step 3 : Import dependencies
To use libraries, import all of them in the main.dart file,
import 'package:image_picker/image_picker.dart';
import 'package:image_editor_plus/image_editor_plus.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
Step 4 : Working With main.dart
Add the boilerplate code below in main.dart to create a basic structure with an AppBar and body using a Scaffold.
Dart
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:image_editor_plus/image_editor_plus.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
// Entry point of the application
void main() {
runApp(const MyApp());
}
// Root widget of the application
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: PhotoEditorApp(),
// Disable debug banner
debugShowCheckedModeBanner: false,
);
}
}
// Stateful widget for the photo editor app
class PhotoEditorApp extends StatefulWidget {
const PhotoEditorApp({Key? key}) : super(key: key);
@override
State<PhotoEditorApp> createState() => _PhotoEditorAppState();
}
class _PhotoEditorAppState extends State<PhotoEditorApp> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Image Editor Plus"),
backgroundColor: Colors.green,
foregroundColor: Colors.white,
),
body: Center(
child: // Code Here
),
);
}
}
Step 5 : Initialize variables
Intialize required variables.
Dart
// Holds the edited image file
File? _editedImage;
Step 6 : Create methods
Create a method to pick an image from the specified source and edit it using the image_picker and image_editor_plus packages.
Dart
// Function to pick an image from the specified source and edit it
Future<void> _pickAndEditImage(ImageSource source) async {
// Request necessary permissions
await Permission.photos.request();
await Permission.camera.request();
await Permission.storage.request();
// Pick an image using the ImagePicker
final pickedFile = await ImagePicker().pickImage(source: source);
// If no image is selected, return
if (pickedFile == null) return;
final imageFile = File(pickedFile.path);
// Open the image editor
final editedImage = await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ImageEditor(image: imageFile.readAsBytesSync()),
),
);
// If an edited image is returned, save it to a temporary directory
if (editedImage != null) {
final tempDir = await getTemporaryDirectory();
final filePath = '${tempDir.path}/edited_${DateTime.now().millisecondsSinceEpoch}.png';
final file = File(filePath);
await file.writeAsBytes(editedImage);
// Update the state with the edited image
setState(() {
_editedImage = file;
});
// Show a success message
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Image Edited Successfully')),
);
}
}
Step 7 : Develop UI
– ElevatedButton : Used to select images from the camera and gallery.
Dart
// Button to edit an image from the camera
ElevatedButton.icon(
style: ElevatedButton.styleFrom(
// Button background color
backgroundColor: Colors.green,
// Button text/icon color
foregroundColor: Colors.white,
),
// Camera icon
icon: const Icon(Icons.camera_alt),
// Button label
label: const Text("Edit from Camera"),
onPressed: () => _pickAndEditImage(ImageSource.camera),
),
// Button to edit an image from the gallery
ElevatedButton.icon(
style: ElevatedButton.styleFrom(
// Button background color
backgroundColor: Colors.green,
// Button text/icon color
foregroundColor: Colors.white,
),
// Gallery icon
icon: const Icon(Icons.photo_library),
// Button label
label: const Text("Edit from Gallery"),
onPressed: () => _pickAndEditImage(ImageSource.gallery),
),
– Image.file() : Display the edited image if available.
Dart
// Display the edited image if available
if (_editedImage != null) Image.file(_editedImage!, height: 300),
– Column : It is used to arrange its child widgets like Image.file() and two ElevatedButtons vertically in a single column.
Dart
Column(
// Center the content
mainAxisAlignment: MainAxisAlignment.center,
children: [
// Display the edited image if available
if (_editedImage != null) Image.file(_editedImage!, height: 300),
// Add spacing
const SizedBox(height: 30),
// Button to edit an image from the camera
ElevatedButton.icon(
style: ElevatedButton.styleFrom(
backgroundColor: Colors.green,
foregroundColor: Colors.white,
),
// Camera icon
icon: const Icon(Icons.camera_alt),
// Button label
label: const Text("Edit from Camera"),
onPressed: () => _pickAndEditImage(ImageSource.camera),
),
// Add spacing
const SizedBox(height: 10),
// Button to edit an image from the gallery
ElevatedButton.icon(
style: ElevatedButton.styleFrom(
backgroundColor: Colors.green,
foregroundColor: Colors.white,
),
// Gallery icon
icon: const Icon(Icons.photo_library),
// Button label
label: const Text("Edit from Gallery"),
onPressed: () => _pickAndEditImage(ImageSource.gallery),
),
],
),
Complete Source Code
main.dart:
Dart
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:image_editor_plus/image_editor_plus.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
// Entry point of the application
void main() {
runApp(const MyApp());
}
// Root widget of the application
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: PhotoEditorApp(),
// Disable debug banner
debugShowCheckedModeBanner: false,
);
}
}
// Stateful widget for the photo editor app
class PhotoEditorApp extends StatefulWidget {
const PhotoEditorApp({Key? key}) : super(key: key);
@override
State<PhotoEditorApp> createState() => _PhotoEditorAppState();
}
class _PhotoEditorAppState extends State<PhotoEditorApp> {
// Holds the edited image file
File? _editedImage;
// Function to pick an image from
// the specified source and edit it
Future<void> _pickAndEditImage(ImageSource source) async {
// Request necessary permissions
await Permission.photos.request();
await Permission.camera.request();
await Permission.storage.request();
// Pick an image using the ImagePicker
final pickedFile = await ImagePicker().pickImage(source: source);
// If no image is selected, return
if (pickedFile == null) return;
final imageFile = File(pickedFile.path);
// Open the image editor
final editedImage = await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ImageEditor(image: imageFile.readAsBytesSync()),
),
);
// If an edited image is returned, save it to a temporary directory
if (editedImage != null) {
final tempDir = await getTemporaryDirectory();
final filePath = '${tempDir.path}/edited_${DateTime.now().millisecondsSinceEpoch}.png';
final file = File(filePath);
await file.writeAsBytes(editedImage);
// Update the state with the edited image
setState(() {
_editedImage = file;
});
// Show a success message
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Image Edited Successfully')),
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
// App bar title
title: const Text("Image Editor Plus"),
// App bar background color
backgroundColor: Colors.green,
// App bar text color
foregroundColor: Colors.white,
),
body: Center(
child: Column(
// Center the content
mainAxisAlignment: MainAxisAlignment.center,
children: [
// Display the edited image if available
if (_editedImage != null) Image.file(_editedImage!, height: 300),
// Add spacing
const SizedBox(height: 30),
// Button to edit an image from the camera
ElevatedButton.icon(
style: ElevatedButton.styleFrom(
// Button background color
backgroundColor: Colors.green,
// Button text/icon color
foregroundColor: Colors.white,
),
// Camera icon
icon: const Icon(Icons.camera_alt),
// Button label
label: const Text("Edit from Camera"),
onPressed: () => _pickAndEditImage(ImageSource.camera),
),
// Add spacing
const SizedBox(height: 10),
// Button to edit an image from the gallery
ElevatedButton.icon(
style: ElevatedButton.styleFrom(
// Button background color
backgroundColor: Colors.green,
// Button text/icon color
foregroundColor: Colors.white,
),
// Gallery icon
icon: const Icon(Icons.photo_library),
// Button label
label: const Text("Edit from Gallery"),
onPressed: () => _pickAndEditImage(ImageSource.gallery),
),
],
),
),
);
}
}
Output:
Similar Reads
Creating a Simple Application in Flutter
Flutter is an open-source cross-platform mobile application development SDK created by Google. It is highly user-friendly and builds high-quality mobile applications. The intention behind this article is to guide readers through the process of building an application through Flutter by creating a si
5 min read
Recipe Finder Application in Flutter
This app will display a list of recipes in a card format, each containing the recipe title, a rating, the cooking time, and a thumbnail image to give users a visual preview. The app is dynamic and flexible, allowing you to easily update the recipe list or modify the UI as needed. By the end of this
5 min read
How to Build a ToDo Application in Flutter?
Flutter offers a stable framework for constructing richly UI-driven cross-platform applications. In this article, we will learn to build a ToDo Flutter Application. What is the ToDo Application?The ToDo application helps users manage and organize their tasks and responsibilities more easily. Managin
6 min read
How to Add Audio File in Flutter Application?
Flutter is a well known tool for developing cross platform applications. It is considered a good choice among developers because of the single code base policy for all types of OS and devices. Flutter engine provides support to vast libraries and file types, its easy to develop beautifull UI by addi
3 min read
Creating a Finance Tracker Application in Flutter
Developing a new tracker for finance is a good practice to improve your skills and build a helpful application. Through Flutter, an open-source UI toolkit developed by Google, it is possible to design for iOS/ Android, web, and desktop. Here you will find out the recipe of how to create a finance tr
6 min read
EBook reader Application in Flutter
EBook reader Application brings the library to your fingertips. This application will be the travel partner of every book lover who loves to read books of their choice. The app is developed using Flutter and provider state management. It uses the Google Books API to fetch the data of books. The app
8 min read
Flutter - Application Device Preview
Flutter got an amazing package called device_preview. Previewing how your app looks or works on different devices is an important part of development. But is a hectic process to try to test on different emulators but still as an individual developer it will be not an easy task for you but also time-
2 min read
Building eCommerce applications with Flutter
Flutter uses the Dart programming language and allows developers to build high-performance, visually attractive mobile applications for both iOS and Android platforms from a single codebase. Flutter is a powerful cross-platform development framework that enables building native-looking apps for both
8 min read
Expense Tracker Application Flutter
In this tutorial, we will create a Flutter app that allows users to track their daily expenses and income, visualize spending patterns through charts, and store transaction data locally using Hive. This application will showcase how to handle user input, visualize data, and ensure local data persist
10 min read
Flutter Quill - Rich Text Editor in Flutter Application
This post will explain how to integrate a rich text editor into your Flutter application so that it may enable rich text editing. There are many more things we can do with Flutter Quill, but they can get a little involved. The example below is a pretty basic demonstration of what we mean. Let's firs
5 min read