A flutter plugin to crop image on iOS and Android.

Overview

Image Cropping plugin for Flutter

A flutter plugin to crop image on iOS and Android.

Image Cropping Preview

The plugin comes with a Crop widget. The widget renders only image, overlay, and handles to crop an image. Thus it can be composed with other widgets to build custom image cropping experience.

The plugin is working with files to avoid passing large amount of data through method channels. Files are stored in cache folders of iOS and Android. Thus if there is a need to save actual croped image, ensure to copy the file to other location.

All of the computation intensive work is done off a main thread via dispatch queues on iOS and cache thread pool on Android.

Note: This plugin is still under development, some features are not available yet and testing has been limited.

Installation

Add image_crop image_crop as a dependency in pubspec.yaml.

Using

Create a widget to load and edit an image:

final cropKey = GlobalKey<CropState>();

Widget _buildCropImage() {
  return Container(
      color: Colors.black,
      padding: const EdgeInsets.all(20.0),
      child: Crop(
        key: cropKey,
        image: Image.file(imageFile),
        aspectRatio: 4.0 / 3.0,
      ),
  );
}

Access cropping values:

  • scale is a factor to proportionally scale image's width and height when cropped. 1.0 is no scale needed.
  • area is a rectangle indicating fractional positions on the image to crop from.
final crop = cropKey.currentState;
// or
// final crop = Crop.of(context);
final scale = crop.scale;
final area = crop.area;

if (area == null) {
    // cannot crop, widget is not setup
    // ...
}

Accessing and workign with images. As a convenience function to request permissions to access photos.

final permissionsGranted = await ImageCrop.requestPermissions();

Read image options, such as: width and height. This is efficent implementation that does not decode nor load actual image into a memory.

final options = await getImageOptions(file: file);
debugPrint('image width: ${options.width}, height: ${options.height}');

If image is large to be loaded into the memory, there is a sampling function that relies on a native platform to proportionally scale down the image befor loading it to the memory. e.g. resample image to get down to 1024x4096 dimension as close as possible. If it is a square preferredSize can be used to specify both width and height. Prefer to leverage this functionality when displaying images in UI.

final sampleFile = await ImageCrop.sampleImage(
    file: originalFile,
    preferredWidth: 1024,
    preferredHeight: 4096,
);

Once Crop widget is ready, there is a native support of croping and scaling an image. In order to produce higher quality cropped image, rely on sampling image with preferred maximum width and height. Scale up a resolution of the sampled image. When cropped, the image is in higher resolution. Example is illustrated below:

final sampledFile = await ImageCrop.sampleImage(
    file: originalFile,
    preferredWidth: (1024 / crop.scale).round(),
    preferredHeight: (4096 / crop.scale).round(),
);

final croppedFile = await ImageCrop.cropImage(
    file: sampledFile,
    area: crop.area,
);
Comments
  • Picture orientation is systematically changed to portrait after cropping on iOs devices only

    Picture orientation is systematically changed to portrait after cropping on iOs devices only

    After cropping a picture in landscape, the orientation is systematically changed to portrait.

    This problem is only on iOs (AMHA is issue resolved in #14 for Android devices).

    bug 
    opened by bubu98 7
  • Not cropping images taken from samsung camera

    Not cropping images taken from samsung camera

    This happens as it does not read meta data of the images. A portrait image is saved in landscape orientation and those details are saved as Exif. When a portrait image is given to the cropper it read its height and width in wrong orientation where width > height.

    bug 
    opened by praneethfdo 7
  •  Fixed image rotation bug after cropping

    Fixed image rotation bug after cropping

    Changed method CGImageSourceCreateImageAtIndex to CGImageSourceCreateThumbnailAtIndex, with CFDictionaryRef contains key kCGImageSourceCreateThumbnailWithTransform : @YES.

    Without transform key image gets rotated by 90 degree

    opened by igorstr 5
  • ImageStreamLister not found

    ImageStreamLister not found

    I am seeing errors in the debug console when i try use Crop.file about a missing image stream listener

    Error: Type 'ImageStreamListener' not found. ImageStreamListener _imageListener; ^^^^^^^^^^^^^^^^^^^ Error: 'ImageStreamListener' isn't a type.

    opened by xenosis 5
  • Handles are moving the image

    Handles are moving the image

    When handles are moved, the image is moved at the same time. This makes it difficult to select a crop area. However curiously the image does not move with the bottom-right handle.

    enhancement 
    opened by Z6P0 5
  • Fixes empty image on first frame

    Fixes empty image on first frame

    This fixes #5

    By calling ensureVisualUpdate we can ensure that the post render function will be called. But a new frame is only created when no other new frame is requested.

    opened by LukBukkit 5
  • How to save crop_image?

    How to save crop_image?

    I need to save cropped image to app temp folder and use later to send via email. So I have a few question.

    1. How can I save cropped image to device?
    2. Separately I need to take 3 picture and crop the images before send via mail. what is the best and fastest way to save these images?

    thanks

    //TODO: CROP IMAGE
    Future<void> _cropImage(BuildContext context) async {
      final scale = cropKey.currentState.scale;
      final area = cropKey.currentState.area;
      if (area == null) {
        // cannot crop, widget is not setup
        return;
      }
    
      // scale up to use maximum possible number of pixels
      // this will sample image in higher resolution to make cropped image larger
      final sample = await ImageCrop.sampleImage(
        file: _file,
        preferredSize: (3000 / scale).round(),
      );
    
      final file = await ImageCrop.cropImage(
        file: sample,
        area: area,
      );
    
    opened by NTMS2017 4
  • Add snap image flag

    Add snap image flag

    Setting 'snapImage' to false will no longer realign the image on end of drag to the middle.

    Defaults to true to keep current behavior on older versions.

    opened by knezzz 4
  • How to use ImageCrop.cropImage alone?

    How to use ImageCrop.cropImage alone?

    This is my code:

    import 'dart:io';
    
    import 'package:flutter/material.dart';
    import 'package:image_crop/image_crop.dart';
    import 'package:image_picker/image_picker.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);
    
      final String title;
    
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      File _image;
    
      Future _getCroppedImage() async {
        File image = await ImagePicker.pickImage(source: ImageSource.gallery);
    
        final croppedFile = await ImageCrop.cropImage(
          file: image,
          area: Rect.fromLTRB(100, 250, 300, 350),
        );
    
        setState(() => _image = croppedFile);
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: Center(
            child:
                _image == null ? Text('Please pick an image') : Image.file(_image),
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: _getCroppedImage,
            child: Icon(Icons.image),
          ),
        );
      }
    }
    

    But after picking an image, program crashes! I only need to crop with certain area. How can I fix this issue?

    opened by AliRezaBeitari 3
  • Initial render of crop area empty

    Initial render of crop area empty

    Hello,

    I've encountered a bug on my OnePlus 5T while using this library. My phone currently runs Android 9, but this also happens with Android 8. This bug doesn't appear in the Android emulator (8 and 9).

    Bug: After I've choosen a picture, there's nothing displayed in the crop area, until I choose a new picture or request a crop.

    Here's a video of the bug: https://youtu.be/ybkYCej60kQ And other thing I've noticed: When I toggle the debug render mode, the image appears. Here's a video of that: https://youtu.be/GvGAfBsTwxw

    Thanks for the useful library πŸ‘

    opened by LukBukkit 3
  • fixed two bugs

    fixed two bugs

    1. bug with portrait images aspectRatio(crop grid is out of boundaries). In the current version crop grid is painted relative to horizontal edges, but vertical(top edge and bottom edge) are not taken into account. This means that crop grid's width is always equal to device screen's width, what, of course, is wrong. This was fixed by checking does crop grid go beyond image boundaries. If so, then we change crop grid width to corresponding to crop grid height.
    2. bug with identification of scaling and moving(dragging) gestures. In the current version for scaling you need to touch with two fingers exactly at the same time, what is pretty hard, to be honest. This was fixed by counting pointers(user fingers on the screen).
    3. Syntax fixes
    opened by radomir9720 2
  • add: initialize view programmatically

    add: initialize view programmatically

    Fix #88.

    new initialParam argument, to initialize the crop view programmatically. current crop parameters can be stored using CropInternal model that can accessed from CropState.

    opened by LeGoffMael 0
  • add: placeholderWidget parameter

    add: placeholderWidget parameter

    • new placeholderWidget parameter to display a widget when the image is null
    • new onLoading function parameter to be aware when the crop area is ready to be used

    also fixed an issue where switching image causes an exception (#85)

    ════════ Exception caught by image resource service ════════════════════════════
    The following assertion was thrown by a synchronously-called image listener:
    Cannot get size during build.
    
    The size of this render object has not yet been determined because the framework is still in the process of building widgets, which means the render tree for this frame has not yet been determined. The size getter should only be called from paint callbacks or interaction event handlers (e.g. gesture callbacks).
    

    example

    here is a video showing how a thumbnail and a loader can be used as placeholder

    opened by LeGoffMael 0
  • new: backgroundColor parameter

    new: backgroundColor parameter

    new backgroundColor parameter to custom the crop mask color, if not set the default color (black) is used. the opacity on active/inactive is not changed.

    | before PR | after PR colors set to gray | | -- | -- | |

    opened by LeGoffMael 0
  • new: disableResize parameter

    new: disableResize parameter

    fix #58, #72

    new disableResize parameter which allows to hide and disable the crop handle in the corners (similar to instagram) the cropHandleSize if now dynamic depending on disableResize value, to not deflate the crop view size when there is no boundaries

    opened by LeGoffMael 0
  • Change of Copyright notice

    Change of Copyright notice

    Hello! According to the Appendix of Apache License 2.0, if you want to license your software under this License you should "attach the boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information". This condition is not met now. Π‘ould you remove the copyright from the text of the license and add a COPYRIGHT NOTICE FILE (like this) in the appropriate form instead (including the year of the software development and your name and surname)? You could also apply the Apache License to your source-code files by attaching the notice as a comment at the top of each file. Thank you in advance!

    Apache.org says:

    Include a copy of the Apache License, typically in a file called LICENSE, in your work, and consider also including a NOTICE file.

    It is also valuable to tag each of your source-code files in case they become detached from the LICENSE file. To apply the Apache License to your source-code files, one approach is to attach the following notice to as a comment at the top of each file. Replace the copyright templates with your own identifying information:

    Copyright [yyyy] [name of copyright owner]

    Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

    opened by lubovtorina 0
  • Poor quality during crop

    Poor quality during crop

    When I take a picture, the image have a good quality, but when I try to use it in Crop, it becomes completely blurry. Here are two screenshots of the image in the camera and during the Crop: Capture d’écran 2022-08-12 aΜ€ 15 37 32 Capture d’écran 2022-08-12 aΜ€ 15 38 24

    This is on emulator (Pixel 4 API 30) but I have the same issue on my physical device (OnePlus 9 Pro).

    You can find my code here

    opened by AlexandreKueny 0
Owner
Volodymyr Lykhonis
Frontend Engineer (Devices). Passionate about GUI. Making things happen.
Volodymyr Lykhonis
Flutter plugin, support android/ios.Support crop, flip, rotate, color martix, mix image, add text. merge multi images.

image_editor The version of readme pub and github may be inconsistent, please refer to github. Use native(objc,kotlin) code to handle image data, it i

FlutterCandies 317 Jan 3, 2023
Album Image is based in photo_manager package and has the same concept as image_picker but with a more attractive interface to choose an image or video from the device gallery, whether it is Android or iOS

Album Image is based in photo_manager package and has the same concept as image_picker but with a more attractive interface to choose an image or vide

Phuong Vu 2 Oct 13, 2022
This is a flutter plugin to detect edges in a live camera, take the picture of detected edges object, crop it, and save.

edge_detection A flutter plugin to detect edges of objects, scan paper, detect corners, detect rectangles. It allows cropping of the detected object i

Sawan Kumar Bundelkhandi 180 Dec 28, 2022
Flutter plugin for selecting images from the Android and iOS image library, taking new pictures with the camera, and edit them before using such as rotation, cropping, adding sticker/text/filters.

advance_image_picker Flutter plugin for selecting multiple images from the Android and iOS image library, taking new pictures with the camera, and edi

Weta Vietnam 91 Dec 19, 2022
A Flutter plugin that provides assets abstraction management APIs without UI integration, you can get assets (image/video/audio) on Android, iOS and macOS.

photo_manager Photo/Assets management APIs for Flutter without UI integration, you can get assets (image/video/audio) from Android, iOS and macOS. 提供相

FlutterCandies 526 Jan 4, 2023
FLUTTER API: Video Editor allows trim, crop, rotate and scale video with a super flexible UI Design

video_editor My other APIs Scroll Navigation Video Viewer Helpers Features Super flexible UI Design. Support actions: Crop Trim Scale Rotate Cover sel

Luis Felipe Murguia Ramos 214 Dec 26, 2022
A Flutter widget to crop images.

image_crop_widget A Flutter widget to crop images. The widget is completely written in Dart and has minimal dependencies. The widget displays the imag

Florian Bauer 11 Nov 29, 2022
Dart library for decoding/encoding image formats, and image processing.

image Overview A Dart library providing the ability to load, save and manipulate images in a variety of different file formats. The library is written

Brendan Duncan 907 Dec 27, 2022
WooCommerce App template that uses Flutter. Integrated to work with WooCommerce stores, connect and create an IOS and Android app from Flutter for IOS and Android

WooCommerce App: Label StoreMax Label StoreMax - v5.3.1 Official WooSignal WooCommerce App About Label StoreMax Label StoreMax is an App Template for

WooSignal 314 Jan 9, 2023
Form builder image picker - Form builder image picker for flutter

form_builder_image_picker Field for picking image(s) from Gallery or Camera for

Ferri Sutanto 0 Jan 28, 2022
Flutter Image add drag sort, Image add drag sort, support click event, delete, add, long press drag sort.

flutter_image_add_drag_sort Flutter Image add drag sort, Image add drag sort, support click event, delete, add, long press drag sort, support video fi

null 5 Jun 23, 2020
Permission plugin for Flutter. This plugin provides a cross-platform (iOS, Android) API to request and check permissions.

Flutter permission_handler plugin The Flutter permission_handler plugin is build following the federated plugin architecture. A detailed explanation o

Baseflow 1.7k Dec 31, 2022
Klutter plugin makes it possible to write a Flutter plugin for both Android and iOS using Kotlin only.

The Klutter Framework makes it possible to write a Flutter plugin for both Android and iOS using Kotlin Multiplatform. Instead of writing platform spe

Gillian 33 Dec 18, 2022
A completely Responsive Image Editor App- Works on Android & iOS

Image Editor App Developed using Flutter with No Plugins (except for picking and saving images)

Rivaan Ranawat 20 Dec 16, 2022
Flutterbodydetection - A flutter plugin that uses MLKit on iOS/Android platforms to enable body pose and mask detection using Pose Detection and Selfie Segmentation APIs for both static images and live camera stream.

body_detection A flutter plugin that uses MLKit on iOS/Android platforms to enable body pose and mask detection using Pose Detection and Selfie Segmen

null 18 Dec 5, 2022
Flutter blue plus - Flutter plugin for connecting and communicationg with Bluetooth Low Energy devices, on Android and iOS

Introduction FlutterBluePlus is a bluetooth plugin for Flutter, a new app SDK to

null 141 Dec 22, 2022
A Flutter Plugin for Volume Control and Monitoring, support iOS and Android

flutter_volume A flutter plugin for volume control and monitoring, support iOS and Android ζ‰‹ζŠŠζ‰‹εΈ¦δ½ ε†™ Flutter η³»η»ŸιŸ³ι‡ζ’δ»Ά https://www.yuque.com/befovy/share/fl

befovy 35 Dec 9, 2022
Flutter Downloader - A plugin for creating and managing download tasks. Supports iOS and Android.

Flutter Downloader A plugin for creating and managing download tasks. Supports iOS and Android. This plugin is based on WorkManager in Android and NSU

Flutter Community 789 Jan 3, 2023