πŸ“¦ image_picker_adapter

A highly customizable, cross-platform image picking, cropping, and compression toolkit built on top of Flutter's image_picker, image_cropper, and flutter_image_compress. This adapter provides a modular, testable, and UI-agnostic solution for seamless image selection and preprocessing in your apps.


πŸš€ Features

  • βœ… Platform-aware image selection from camera or gallery
  • βœ‚οΈ Optional image cropping (with customizable UI)
  • πŸ—œοΈ Optional image compression
  • 🧩 Modular architecture (SOLID principles)
  • πŸ”„ Supports Cubit for state-driven image picking
  • πŸ–ΌοΈ Custom UI builders for both avatar and image pickers
  • πŸ“¦ Easy to plug into any Flutter app via DI and BlocProvider

πŸ“¦ Installation

Add the following to your pubspec.yaml:

dependencies:
  image_picker_adapter: latest_version

Then run:

flutter pub get

🧱 Architecture Overview

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚    AppImagePicker        β”‚ ◄── Customizable Widget
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  ↳ ImagePickerCubit      β”‚ ◄── Handles image picking states
β”‚  ↳ ImagePickerManager    β”‚ ◄── Coordinates services
β”‚     ↳ AppImagePickerService
β”‚     ↳ IImageCropperService
β”‚     ↳ IImageCompressorService
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ› οΈ Getting Started

1. βœ… Register Dependencies

void registerImagePickerAdapterDependencies() {
  sl.registerLazySingleton<AppImagePickerService>(() => AppImagePickerService());
  sl.registerLazySingleton<IImageCropperService>(() => AppImageCropperService());
  sl.registerLazySingleton<IImageCompressorService>(() => AppImageCompressorService());

  sl.registerLazySingleton<ImagePickerManager>(
    () => ImagePickerManager(
      pickerService: sl<AppImagePickerService>(),
      cropperService: sl<IImageCropperService>(),
      compressorService: sl<IImageCompressorService>(),
    ),
  );

  sl.registerFactory(
    () => ImagePickerCubit(imagePickerManager: sl<ImagePickerManager>()),
  );
}

2. 🧠 Provide Bloc

List<SingleChildWidget> imagePickerAdapterBlocProviders = [
  BlocProvider<ImagePickerCubit>(create: (_) => sl<ImagePickerCubit>()),
];

3. 🎨 Use AppImagePicker Widget

AppImagePicker(
  imageQuality: 80,
  crop: true,
  compress: true,
  onChanged: (file) {
    // Do something with XFile
  },
  builder: (file) => CircleAvatar(
    backgroundImage: file != null ? FileImage(File(file.path)) : null,
  ),
)

πŸ‘€ Avatar Picker Example

AvatarImagePicker(
  imageSource: user.avatarUrl,
  radius: 40,
  crop: true,
  compress: true,
  onChanged: (file) => print('Picked: ${file?.path}'),
)

πŸ§ͺ Extension Utilities

extension XFileParserExtension on XFile {
  Future<T?> parseAs<T>() async {
    if (T == File) return File(path) as T;
    if (T == Uint8List) return await readAsBytes() as T;
    if (T == String) return path as T;
    if (T == XFile) return this as T;
    throw UnsupportedError('Unsupported type conversion: $T');
  }
}

🧭 Source Selector Modes

  • bottomSheet (default)
  • alertDialog
  • custom

You can inject your own selector widget or use built-in ones like SourceSelectorDialog or ImageSourceSelector.


🧩 Customization

  • Build your own image viewer UI with builder in AppImagePicker
  • Customize source selection UI via IImageSourceSelectorService
  • Provide your own crop/compress service by implementing IImageCropperService, IImageCompressorService

πŸ“„ License

MIT License


πŸ™Œ Contributions

Feel free to open issues, pull requests or contribute ideas to enhance the image_picker_adapter.


🧠 Credits


πŸ‘¨β€πŸ’Ό Author

image_picker_adapter Developed with ❀️ by Shohidul Islam