pub package package publisher style license

A Flutter plugin which supports native circular and rectangular cropping.

Preview example


  • Better performance, since it is written in Kotlin/Swift
  • Usable without widget
  • Circular and rectangular cropping
  • Customizable drag points
  • Customizable crop mask
  • Customizable hit size


Depend on it:

  native_image_cropper: ^0.4.0

Import it:

import 'package:native_image_cropper/native_image_cropper.dart';

Minimal example:

  body: CropPreview(
  bytes: imageData,

Customization options:

final maskOptions = const MaskOptions(
  backgroundColor: Colors.black38,
  borderColor: Colors.grey,
  strokeWidth: 2,
  aspectRatio: 4 / 3,
  minSize: 0,

  mode: CropMode.rect,
  dragPointSize: 20,
  hitSize: 20,
  maskOptions: maskOptions,
  dragPointBuilder: (size, position) {
  if (position == CropDragPointPosition.topLeft) {
    return CropDragPoint(size: size, color:;
  return CropDragPoint(size: size, color:;

Crop an image:

To crop an image you can pass a CropController to CropPreview:

final controller = CropController();

CropPreview(controller: controller, bytes: imageData);

final croppedBytes = await controller.crop();

or call it directly using MethodChannels:

final croppedBytes = await NativeImageCropper.cropRect(
  bytes: imageData,
  x: 0,
  y: 0,
  width: 500,
  height: 500,
final croppedBytes = await NativeImageCropper.cropOval(
  bytes: imageData,
  x: 0,
  y: 0,
  width: 500,
  height: 500,

Limitations on the web platform

The Flutter engine Skia does not support JPEG. Therefore, our package currently only supports cropping to PNG format. On the web platform, isolates are not supported for concurrency, which means that the UI may freeze for large images. However, we plan to implement a solution for JPEG support in the future, and we will also look into utilizing web workers to run scripts in background threads, similar to isolates.

Also it is not possible render the crop mask properly due to an issue on the web platform. To disable the crop mask you have to set the background color of the mask to transparent.

final maskOptions = const MaskOptions(backgroundColor: Colors.transparent);