picker_image_cropper 0.0.5
picker_image_cropper: ^0.0.5 copied to clipboard
A modern Flutter package for selecting and cropping images with a professional UI and advanced features.
picker_image_cropper #
A modern Flutter package for selecting and cropping images with a professional UI and advanced features. Supports Android, iOS, Web, Windows, macOS, and Linux.
Features #
- Pick images from the gallery or capture directly from the camera
- Draggable, resizable crop box with corner and edge handles
- Rectangle and circle crop overlays
- Multiple aspect ratios: Free, 1:1, 4:3, 16:9, 3:4
- Rotate image in 90° steps
- Zoom and pan with
InteractiveViewer - Toggle grid overlay for alignment
- Output as
Uint8Listbytes, file path, or both - Dark, light, and blue built-in themes
- Fully cross-platform — no
dart:ioin the public API - Internationalization support via
CropperLabels
Installation #
dependencies:
picker_image_cropper: ^0.0.5
Permissions #
Android #
Add to android/app/src/main/AndroidManifest.xml:
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
iOS #
Add to ios/Runner/Info.plist:
<key>NSCameraUsageDescription</key>
<string>Required to capture photos</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Required to pick images</string>
Usage #
Pick from gallery and crop #
final result = await ImagePickerCropper.pickAndCrop(
context: context,
outputType: OutputType.bytes,
);
if (result != null && result.hasBytes) {
// use result.bytes
}
Capture from camera and crop #
final result = await ImagePickerCropper.capturePhoto(
context: context,
outputType: OutputType.both,
);
if (result != null) {
final bytes = result.bytes; // Uint8List?
final path = result.filePath; // String? — use File(path!) on native
}
Crop an existing image by path #
final result = await ImagePickerCropper.cropImage(
context: context,
imagePath: '/path/to/image.jpg',
outputType: OutputType.bytes,
);
Callback-based API #
await ImagePickerCropper.pickAndCropWithCallback(
context: context,
onCompleted: (String? filePath, Uint8List? bytes) {
// handle result
},
onBytesCompleted: (Uint8List bytes) {
// bytes only
},
onFileCompleted: (String filePath) {
// file path only — reconstruct File(filePath) on native if needed
},
);
Use ModernImageCropper widget directly #
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => ModernImageCropper(
imageFile: xFile, // XFile, _XFileWrapper, or String path
aspectRatio: 1.0, // 0.0 = free
overlayType: CropOverlayType.circle,
outputType: OutputType.bytes,
theme: CropperTheme.dark,
onCropCompletedWithResult: (CropResult result) {
// result.bytes, result.filePath
},
onCancelled: () => Navigator.pop(context),
),
),
);
CropResult #
| Property | Type | Description |
|---|---|---|
bytes |
Uint8List? |
Cropped image as bytes |
filePath |
String? |
Path to the saved temp file |
hasBytes |
bool |
Whether bytes are present |
hasFile |
bool |
Whether a file path is present |
isEmpty |
bool |
True when both are null |
bytesSize |
int |
Size of bytes in bytes |
On native platforms you can reconstruct a
dart:io Filewith:import 'dart:io'; final file = File(result.filePath!);
OutputType #
| Value | Description |
|---|---|
OutputType.bytes |
Return bytes only (default) |
OutputType.file |
Save to temp file and return path |
OutputType.both |
Return both bytes and file path |
Themes #
CropperTheme.dark // default
CropperTheme.light
CropperTheme.blue
Or build your own:
CropperTheme(
backgroundColor: Colors.black,
appBarColor: Colors.grey[900]!,
cropBorderColor: Colors.white,
// ...
)
Internationalization #
ModernImageCropper(
labels: CropperLabels(
cropImageTitle: 'Crop Image',
cropButtonText: 'Done',
rotateButtonText: 'Rotate',
resetButtonText: 'Reset',
gridButtonText: 'Grid',
ratioText: 'Ratio',
shapeText: 'Shape',
loadingImageText: 'Loading...',
errorLoadingImageText: 'Error loading image',
failedToLoadImageText: 'Failed to load image',
),
// ...
)
A Persian preset is included: CropperLabels.persian.
Platform notes #
- Web: File output (
OutputType.file) returnsnullforfilePathsince the browser has no writable file system. UseOutputType.byteson web. - WASM: Fully compatible — no
dart:ioin the compilation path. - Windows / Linux / macOS: Full support including file output to the system temp directory.