Image Picker Master
A comprehensive Flutter plugin for picking images, videos, audio files, documents, and any file type — with multiple selection, compression, Unicode filename support, and camera capture — across all platforms.
Platform Support
| Platform | Pick Files | Camera Capture | Multiple Select | Compression |
|---|---|---|---|---|
| Android | ✅ | ✅ | ✅ | ✅ |
| iOS | ✅ | ✅ | ✅ | ✅ |
| macOS | ✅ | ✅ | ✅ | ✅ |
| Windows | ✅ | ✅ | ✅ | ✅ |
| Linux | ✅ | ✅ | ✅ | ✅ |
| Web | ✅ | ✅ | ✅ | ✅ |
Features
- ✅ Cross-platform — Android, iOS, macOS, Windows, Linux, Web
- ✅ All file types — Images, videos, audio, documents, archives, fonts, code files
- ✅ Camera capture — Take photos directly from the camera on all platforms
- ✅ Multiple selection — Pick several files at once
- ✅ Image compression — Quality control from 0 to 100
- ✅ File bytes — Optionally load raw bytes into memory (
withData: true) - ✅ MIME type detection — Automatic detection for all file types
- ✅ Unicode filenames — Full support for Persian/Farsi, Arabic, Chinese, and all Unicode scripts
- ✅ Temporary file cleanup — Built-in
clearTemporaryFiles()to free disk space - ✅ Custom extensions — Filter picker to any file extension you choose
- ✅ Runtime permissions — Camera and storage permissions requested automatically (Android/iOS)
Installation
Add to your pubspec.yaml:
dependencies:
image_picker_master: ^0.0.5
Then run:
flutter pub get
Setup
Android
No manual setup required. The plugin automatically requests CAMERA and storage permissions at runtime.
The following are declared in the plugin's AndroidManifest.xml — you do not need to add them to your app:
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
iOS
Add these keys to your ios/Runner/Info.plist:
<key>NSCameraUsageDescription</key>
<string>This app uses the camera to capture photos and videos.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>This app accesses your photo library to pick images and videos.</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>This app saves captured photos to your photo library.</string>
<key>NSMicrophoneUsageDescription</key>
<string>This app uses the microphone to record video audio.</string>
Note: If you use the plugin's podspec
script_phase(included by default), these keys are injected automatically at build time when missing.
macOS
Add to your macos/Runner/Info.plist:
<key>NSCameraUsageDescription</key>
<string>This app uses the camera to capture photos.</string>
<key>NSMicrophoneUsageDescription</key>
<string>This app uses the microphone.</string>
And to your macos/Runner/DebugProfile.entitlements and macos/Runner/Release.entitlements:
<key>com.apple.security.device.camera</key>
<true/>
<key>com.apple.security.device.microphone</key>
<true/>
Note: The plugin's podspec
script_phaseinjects these automatically when missing.
Quick Start
import 'package:image_picker_master/image_picker_master.dart';
// Pick a single image
final image = await ImagePickerMaster.instance.pickImage();
// Pick multiple images
final images = await ImagePickerMaster.instance.pickImages();
// Capture a photo
final photo = await ImagePickerMaster.instance.capturePhoto();
// Pick a PDF/Word document
final doc = await ImagePickerMaster.instance.pickDocument();
// Pick any file type
final files = await ImagePickerMaster.instance.pickFiles(
type: FileType.all,
allowMultiple: true,
);
Usage Guide
1. pickFiles() — Pick any file type
// Pick all file types
final files = await ImagePickerMaster.instance.pickFiles(
type: FileType.all,
allowMultiple: true,
);
// Pick images with compression
final images = await ImagePickerMaster.instance.pickFiles(
type: FileType.image,
allowMultiple: true,
allowCompression: true,
compressionQuality: 75,
withData: true,
);
// Pick only specific extensions
final custom = await ImagePickerMaster.instance.pickFiles(
type: FileType.custom,
allowedExtensions: ['pdf', 'docx', 'xlsx'],
allowMultiple: true,
);
if (files != null) {
for (final file in files) {
print('${file.name} — ${file.size} bytes — ${file.mimeType}');
}
}
2. pickImage() / pickImages() — Images
// Single image
final image = await ImagePickerMaster.instance.pickImage(
allowCompression: true,
compressionQuality: 80,
withData: true,
);
if (image != null) {
print('Path: ${image.path}');
print('Size: ${(image.size / 1024).toStringAsFixed(1)} KB');
if (image.bytes != null) {
// Use raw bytes directly — e.g. Image.memory(image.bytes!)
}
}
// Multiple images
final images = await ImagePickerMaster.instance.pickImages(
allowMultiple: true,
allowCompression: true,
compressionQuality: 85,
);
3. pickVideo() / pickVideos() — Videos
final video = await ImagePickerMaster.instance.pickVideo();
if (video != null) {
print('${video.name} — ${(video.size / 1024 / 1024).toStringAsFixed(2)} MB');
}
final videos = await ImagePickerMaster.instance.pickVideos(allowMultiple: true);
4. pickAudio() / pickAudios() — Audio
final audio = await ImagePickerMaster.instance.pickAudio(withData: true);
if (audio != null && audio.bytes != null) {
print('Audio bytes loaded: ${audio.bytes!.length}');
}
final audios = await ImagePickerMaster.instance.pickAudios();
5. pickDocument() / pickDocuments() — Documents
// Single document
final doc = await ImagePickerMaster.instance.pickDocument(
allowedExtensions: ['pdf', 'docx', 'txt'],
withData: true,
);
// Multiple documents
final docs = await ImagePickerMaster.instance.pickDocuments(
allowMultiple: true,
);
if (docs != null) {
for (final doc in docs) {
final ext = doc.name.split('.').last.toLowerCase();
print('[$ext] ${doc.name} — ${(doc.size / 1024).toStringAsFixed(1)} KB');
}
}
6. capturePhoto() — Camera
// Basic capture
final photo = await ImagePickerMaster.instance.capturePhoto();
// Compressed capture ready for upload
final photo = await ImagePickerMaster.instance.capturePhoto(
allowCompression: true,
compressionQuality: 70,
withData: true,
);
if (photo != null) {
print('Captured: ${photo.name}');
print('Size: ${(photo.size / 1024).toStringAsFixed(1)} KB');
// photo.bytes contains raw JPEG data when withData: true
}
7. clearTemporaryFiles() — Cleanup
Call this to free disk space used by the plugin's temp copies:
// In State.dispose()
@override
void dispose() {
ImagePickerMaster.instance.clearTemporaryFiles();
super.dispose();
}
// Or on app lifecycle changes
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.paused) {
ImagePickerMaster.instance.clearTemporaryFiles();
}
}
PickedFile Object
Every pick operation returns PickedFile (or List<PickedFile>):
class PickedFile {
final String path; // Absolute path to the temp copy
final String name; // Filename including extension (Unicode safe)
final int size; // File size in bytes
final String? mimeType; // e.g. "image/jpeg", "application/pdf"
final Uint8List? bytes; // Raw bytes — only when withData: true
}
Common patterns with PickedFile
// Show image from bytes
if (file.bytes != null) {
Image.memory(file.bytes!)
}
// Show image from path (mobile/desktop)
Image.file(File(file.path))
// Format size
String formatSize(int bytes) {
if (bytes < 1024) return '$bytes B';
if (bytes < 1024 * 1024) return '${(bytes / 1024).toStringAsFixed(1)} KB';
return '${(bytes / 1024 / 1024).toStringAsFixed(2)} MB';
}
// Get extension
final ext = file.name.split('.').last.toLowerCase();
// Categorize files
bool isImage = file.mimeType?.startsWith('image/') ?? false;
bool isVideo = file.mimeType?.startsWith('video/') ?? false;
bool isAudio = file.mimeType?.startsWith('audio/') ?? false;
API Reference
Methods
| Method | Returns | Description |
|---|---|---|
getPlatformVersion() |
Future<String?> |
Platform OS version string |
pickFiles({...}) |
Future<List<PickedFile>?> |
Pick one or more files of any type |
pickImage({...}) |
Future<PickedFile?> |
Pick a single image |
pickImages({...}) |
Future<List<PickedFile>?> |
Pick multiple images |
pickVideo({...}) |
Future<PickedFile?> |
Pick a single video |
pickVideos({...}) |
Future<List<PickedFile>?> |
Pick multiple videos |
pickAudio({...}) |
Future<PickedFile?> |
Pick a single audio file |
pickAudios({...}) |
Future<List<PickedFile>?> |
Pick multiple audio files |
pickDocument({...}) |
Future<PickedFile?> |
Pick a single document |
pickDocuments({...}) |
Future<List<PickedFile>?> |
Pick multiple documents |
capturePhoto({...}) |
Future<PickedFile?> |
Capture photo from camera |
clearTemporaryFiles() |
Future<void> |
Delete all plugin temp files |
pickFiles Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
type |
FileType |
FileType.all |
File category filter |
allowMultiple |
bool |
false |
Allow selecting multiple files |
allowedExtensions |
List<String>? |
null |
Required when type is FileType.custom |
withData |
bool |
false |
Load file bytes into memory |
allowCompression |
bool |
false |
Compress images before returning |
compressionQuality |
int? |
80 |
JPEG quality 0–100 (100 = lossless) |
FileType Enum
enum FileType {
all, // No filter — all files visible
image, // JPEG, PNG, GIF, BMP, WebP, HEIC, AVIF, SVG, ICO, TIFF
video, // MP4, MOV, AVI, MKV, WMV, FLV, WebM, 3GP, M4V
audio, // MP3, WAV, M4A, FLAC, OGG, AAC, WMA, AIFF
document, // PDF, Word, Excel, PowerPoint, TXT, ODT, EPUB, HTML, ZIP, and more
custom, // Filtered by allowedExtensions list
}
Supported Formats
Images (click to expand)
JPEG, PNG, GIF, BMP, TIFF, WebP, HEIC, HEIF, AVIF, SVG, ICO
Videos (click to expand)
MP4, AVI, MOV, MKV, WMV, FLV, WebM, 3GP, M4V
Audio (click to expand)
MP3, WAV, M4A, FLAC, OGG, AAC, WMA, AIFF
Documents (click to expand)
PDF, DOC/DOCX, XLS/XLSX, PPT/PPTX, TXT, RTF, Markdown, ODT/ODS/ODP, Pages/Numbers/Keynote, EPUB, HTML, CSS, JS, JSON, XML, CSV, YAML, ZIP, RAR, 7Z, TAR, GZ, TTF, OTF, WOFF
Unicode Support
Full support for non-Latin filenames:
// These all work correctly
// Persian: فاکتور.pdf تصویر.jpg
// Arabic: ملف.docx صورة.png
// Chinese: 文档.txt 图片.jpeg
// Japanese: 写真.heic
// Korean: 파일.mp4
Example App
See the example/ directory for a complete working demo of all features.
Changelog
See CHANGELOG.md for the full version history.
Contributing
Pull requests and issues are welcome at github.com/SwanFlutter/image_picker_master.
License
MIT License — see LICENSE for details.
Contact
For questions or feedback: swan.dev1993@gmail.com