Cross‑platform Image Picker & Camera Library (Android & iOS)
Built with Kotlin Multiplatform + Compose Multiplatform + Kotlin/Native
Español • GitHub • Maven Central • Discord
Camera Usage | Crop Mode |
---|---|
![]() |
![]() |
Camera Usage | Crop Mode |
---|---|
![]() |
![]() |
- Cross-platform: Works seamlessly on Android and iOS
- Camera Integration: Direct camera access with photo capture
- Gallery Selection: Pick images from device gallery with compression support
- Advanced Image Cropping: Cross-platform crop functionality with automatic context management
- Automatic Image Compression: Optimize image size while maintaining quality
- Configurable Compression Levels: LOW, MEDIUM, HIGH compression options
- Async Processing: Non-blocking UI with Kotlin Coroutines integration
- Multiple Format Support: JPEG, PNG, HEIC, HEIF, WebP, GIF, BMP
- Customizable UI: Custom dialogs and confirmation views
- Permission Handling: Smart permission management for both platforms
- Easy Integration: Simple API with Compose Multiplatform
- Enhanced User Experience: Improved layout system with proper zoom and aspect ratio handling
- Highly Configurable: Extensive customization options
In your commonMain
build.gradle.kts
:
dependencies {
implementation("io.github.ismoy:imagepickerkmp:1.0.24-beta")//lastversion
}
Even if you're not using KMP, you can use ImagePickerKMP in pure Android projects with Jetpack Compose.
implementation("io.github.ismoy:imagepickerkmp:1.0.24-beta")
Don't forget to configure iOS-specific permissions in your Info.plist
file:
<key>NSCameraUsageDescription</key>
<string>We need access to the camera to capture a photo.</string>
var showCamera by remember { mutableStateOf(false) }
var capturedPhoto by remember { mutableStateOf<PhotoResult?>(null) }
if (showCamera) {
ImagePickerLauncher(
config = ImagePickerConfig(
enableCrop = false, // Set to true if you want Crop option
onPhotoCaptured = { result ->
capturedPhoto = result
// Now you can access result.fileSize for camera captures too!
println("Camera photo size: ${result.fileSize}KB")
showCamera = false
},
onError = {
showCamera = false
},
onDismiss = {
showImagePicker = false // Reset state when user doesn't select anything
},
directCameraLaunch = false, // Set to true if you want to launch the camera directly Only IOS
// It is possible to compress images, by default it is with low compression in the library
cameraCaptureConfig = CameraCaptureConfig(
compressionLevel = CompressionLevel.HIGH
)
)
)
}
var showGallery by remember { mutableStateOf(false) }
var selectedImages by remember { mutableStateOf<List<GalleryPhotoHandler.PhotoResult>>(emptyList()) }
if (showGallery) {
GalleryPickerLauncher(
onPhotosSelected = { photos ->
selectedImages = photos
showGallery = false
},
onError = { error ->
showGallery = false
},
onDismiss = {
println("User cancelled or dismissed the picker")
showGallery = false // Reset state when user doesn't select anything
},
enableCrop = false, // Set to true if you want Crop option
allowMultiple = true, // False for single selection
mimeTypes = listOf(MimeType.IMAGE_PNG) ,// Optional: filter by type
)
}
Button(onClick = { showGallery = true }) {
Text("Choose from Gallery")
}
For more customization (confirmation views, MIME filtering, etc.), check out the integration guide for KMP.
Automatically optimize image size while maintaining quality with configurable compression levels.
- LOW: 95% quality, max 2560px dimension - Best quality, larger files
- MEDIUM: 75% quality, max 1920px dimension - Balanced quality/size
- HIGH: 50% quality, max 1280px dimension - Smaller files, good for storage
- JPEG (image/jpeg) - Full compression support
- PNG (image/png) - Full compression support
- HEIC (image/heic) - Full compression support
- HEIF (image/heif) - Full compression support
- WebP (image/webp) - Full compression support
- GIF (image/gif) - Full compression support
- BMP (image/bmp) - Full compression support
Cross-platform compatibility with intelligent context management and enhanced crop functionality
- Android: The library automatically manages the context using
LocalContext.current
. No need to pass context manually. - iOS: Context is not required as the library uses native iOS APIs. Enhanced crop coordinate calculations ensure consistent behavior with Android.
- Cross-platform Crop: Unified
applyCrop
function with automatic context management and consistent coordinate calculations across platforms.
- 🔄 Automatic Context Management: The
applyCrop
function is now@Composable
and handles Android context automatically - 🖼️ Enhanced iOS Crop Accuracy: Fixed coordinate calculations for precise image cropping on iOS
- 🎯 Improved Layout System: Resolved z-index conflicts and zoom overlay issues for better user experience
- 📱 Better Aspect Ratio Support: Enhanced handling of vertical aspect ratios (like 9:16) with improved space management
Platform | Minimum Version | Status |
---|---|---|
Android | API 21+ | ✅ |
iOS | iOS 12.0+ | ✅ |
Compose Multiplatform | 1.5.0+ | ✅ |
The most comprehensive and developer-friendly image picker for Kotlin Multiplatform
Feature | ImagePickerKMP |
---|---|
Compose Multiplatform Support | ✅ Native |
UI Customization | ✅ Full control |
Unified Permissions | ✅ Smart handling |
Error Handling | ✅ Comprehensive |
Camera Integration | ✅ Direct access |
Gallery Support | ✅ Multi-select |
Cross-platform API | ✅ Single codebase |
- ** Compose Multiplatform Native**: Built specifically for Compose Multiplatform, ensuring consistent behavior across platforms
- ** Full UI Customization**: Complete control over dialogs, confirmation views, and camera UI
- ** Smart Permission Management**: Unified permission handling with intelligent fallbacks
- ** Performance Optimized**: Efficient image processing and memory management
- ** Developer Friendly**: Simple API with comprehensive error handling
- Minimum SDK: 21
- Kotlin 1.8+
- Compose Multiplatform
- iOS 12.0+
- Xcode 14+
- Kotlin Multiplatform
Comprehensive guides and references for every aspect of ImagePickerKMP
- Integration Guide - Complete setup and integration guide
- Customization Guide - UI and behavior customization
- Internationalization Guide - Multi-language support guide
- Permissions Guide - Permission handling details
- Coverage Guide - Code coverage and testing guide
- Notifications Setup - Discord notifications setup
- API Reference - Complete API documentation
- Examples - Code examples and use cases
We welcome contributions from the community!
See our Contributing Guide for details.
Get help, report issues, or join our community
📧 Email • 🐛 Issues • 📖 Wiki • 💬 Discord
Made with ❤️ for the Kotlin Multiplatform community
Star ⭐ this repo if it helped you!