Cross-platform Image Picker & Camera Library for Kotlin Multiplatform
Supports Android, iOS, Desktop, and Web with a unified API. Built with Compose Multiplatform.
Kotlin Multiplatform:
dependencies {
implementation("io.github.ismoy:imagepickerkmp:{latest-version}")
}React/JavaScript:
npm install imagepickerkmpCamera Capture:
var showCamera by remember { mutableStateOf(false) }
var capturedPhoto by remember { mutableStateOf<PhotoResult?>(null) }
if (showCamera) {
ImagePickerLauncher(
config = ImagePickerConfig(
onPhotoCaptured = { result ->
capturedPhoto = result
showCamera = false
},
onError = { showCamera = false },
onDismiss = { showCamera = false }
)
)
}
Button(onClick = { showCamera = true }) {
Text("Take Photo")
}Gallery Selection:
var showGallery by remember { mutableStateOf(false) }
var selectedImages by remember { mutableStateOf<List<PhotoResult>>(emptyList()) }
if (showGallery) {
GalleryPickerLauncher(
onPhotosSelected = { photos ->
selectedImages = photos
showGallery = false
},
onError = { showGallery = false },
onDismiss = { showGallery = false },
allowMultiple = true
)
}
Button(onClick = { showGallery = true }) {
Text("Choose from Gallery")
}Camera Preview Not Showing? Some developers have reported that the camera usage indicator appears, but the preview doesn't show up. This happens when ImagePickerLauncher is not placed inside a visible container composable.
✅ Correct usage:
Box(modifier = Modifier.fillMaxSize()) {
if (showCamera) {
ImagePickerLauncher(
config = ImagePickerConfig(
onPhotoCaptured = { /* handle image */ },
onDismiss = { showCamera = false }
)
)
}
}❌ Incorrect usage:
if (showCamera) {
ImagePickerLauncher(
config = ImagePickerConfig(
onPhotoCaptured = { /* handle image */ },
onDismiss = { showCamera = false }
)
)
}💡 Always wrap the camera launcher inside a composable container (Box, Column, Row) and control its visibility with state.
Thanks to @rnstewart and other contributors for pointing this out! 🙏
- Cross-platform - Android, iOS, Desktop, Web
- Camera & Gallery - Direct access with unified API
- Image Cropping - Built-in crop functionality
- Smart Compression - Configurable quality levels
- Extension Functions - Easy image processing (
loadPainter(),loadBytes(),loadBase64()) - Permission Handling - Automatic permission management
- Async Processing - Non-blocking UI with coroutines
- Format Support - JPEG, PNG, HEIC, HEIF, WebP, GIF, BMP
| Platform | Minimum Version | Status |
|---|---|---|
| Android | API 21+ | ✅ |
| iOS | iOS 12.0+ | ✅ |
| Desktop | JDK 11+ | ✅ |
| Web | Modern Browsers | ✅ |
Experience ImagePickerKMP in action:
- Mobile Demos - Android & iOS camera/gallery functionality
- Desktop Demo - File picker and image processing
- Web Demo - React integration with WebRTC camera
- Crop Demo - Interactive image cropping across platforms
Full-featured sample application showcasing:
- All library features and configurations
- Real-world implementation patterns
- Platform-specific optimizations
- Best practices and tips
| Resource | Description |
|---|---|
| Integration Guide | Complete setup and configuration |
| Customization Guide | UI customization and theming |
| React Guide | Web development setup |
| Permissions Guide | Platform permissions |
| API Reference | Complete API documentation |
ImagePickerLauncher(
config = ImagePickerConfig(
cameraCaptureConfig = CameraCaptureConfig(
compressionLevel = CompressionLevel.HIGH, // LOW, MEDIUM, HIGH
skipConfirmation = true
)
)
)GalleryPickerLauncher(
allowMultiple = true,
mimeTypes = listOf(MimeType.IMAGE_JPEG, MimeType.IMAGE_PNG),
enableCrop = true
)Add to your Info.plist:
<key>NSCameraUsageDescription</key>
<string>Camera access needed to take photos</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Photo library access needed to select images</string>Process images easily with built-in extension functions:
ImagePickerLauncher(
config = ImagePickerConfig(
onPhotoCaptured = { result ->
val imageBytes = result.loadBytes() // ByteArray for file operations
val imagePainter = result.loadPainter() // Painter for Compose UI
val imageBitmap = result.loadImageBitmap() // ImageBitmap for graphics
val imageBase64 = result.loadBase64() // Base64 string for APIs
}
)
)ImagePickerKMP is available as an NPM package for web development:
npm install imagepickerkmpFeatures:
- WebRTC Camera Access - Mobile & desktop camera support
- TypeScript Support - Full type definitions included
- Drag & Drop - File picker with drag and drop
- React Components - Ready-to-use React components
- Cross-Framework - Works with React, Vue, Angular, Vanilla JS
Complete React Integration Guide →
Made with ❤️ for the Kotlin Multiplatform community
⭐ Star this repo if it helped you!