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.

Features
- Flexible
Cropwidget you can place anywhere (full screen, dialog, sheet) CropControllerfor 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
ImageCompressCropPagewith 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.