flutter_image_crop_compress

Crop and compress images in Flutter with a flexible Crop widget, rotate/flip controls, JPEG/PNG quality options, and an optional ready-made editor page.

Image Compress and Crop Preview

Features

  • Flexible Crop widget you can place anywhere (full screen, dialog, sheet)
  • CropController for crop, aspect ratio, circle UI, rotate, flip, reset
  • Rect or circle crop UI
  • Fixed or free aspect ratio
  • Rule-of-thirds grid overlay
  • Compress with quality, max width/height, JPEG or PNG (ImageCompressor)
  • Ready-made ImageCompressCropPage with toolbar + quality slider
  • Runs encode/crop work in a background isolate (compute)

Install

dependencies:
  flutter_image_crop_compress: ^0.1.0

Quick start — ready-made page

Navigator.push(
  context,
  MaterialPageRoute(
    builder: (_) => ImageCompressCropPage(
      imageFile: pickedFile,
      initialQuality: 80,
      initialFormat: ImageOutputFormat.jpeg,
      maxWidth: 1920,
      showGrid: true,
      onTap: (File image) {
        // cropped + compressed file
      },
    ),
  ),
);

Compress only (no UI)

final result = await ImageCompressor.compress(
  bytes,
  options: const CompressOptions(
    quality: 70,
    maxWidth: 1280,
    format: ImageOutputFormat.jpeg,
  ),
);

print('${result.width}x${result.height}, ${result.bytes.length} bytes');

Or write straight to a temp file:

final file = await ImageCompressor.compressToFile(
  bytes,
  options: const CompressOptions(quality: 60, maxWidth: 1024),
);

Custom crop UI

final controller = CropController();

Crop(
  image: imageBytes,
  controller: controller,
  showGrid: true,
  compressOptions: const CompressOptions(
    quality: 85,
    format: ImageOutputFormat.jpeg,
    maxWidth: 1920,
  ),
  onCropped: (bytes) { /* use bytes */ },
  onCroppedResult: (result) {
    // width, height, format, compressionRatio
  },
  onStatusChanged: (status) {
    // CropStatus.ready | CropStatus.cropping
  },
  aspectRatio: 4 / 3,
);

// elsewhere in your UI:
controller.rotateRight();
controller.flipHorizontal();
controller.crop(); // or controller.cropCircle();

Aspect ratio & circle

controller.aspectRatio = 16 / 9;
controller.aspectRatio = null; // free
controller.withCircleUi = true;
controller.cropCircle();

Philosophy

Crop is intentionally minimal so you can embed it in your own design. The package does not pick images from the gallery — use image_picker (or similar) and pass bytes/file in.

Example

See the example/ app for gallery/camera pick, the full editor page, and standalone re-compress.

License

See LICENSE.