ImagePickerKMP

repository·develop·Indexed 41 days ago

https://github.com/ismoy/imagepickerkmp

A modular media library for Android and iOS (including Compose Multiplatform) providing unified APIs for capturing, picking, scanning, and playing photos, videos, and audio. It includes specialized modules such as imagepickerkmp-photo (v1.1.0) for camera and gallery access with cropping and EXIF support, and imagepickerkmp-scanner (v1.0.0-alpha-cans-fix.3) for barcode and QR code scanning. The library features built-in i18n support for multiple languages and cross-platform abstractions for permissions and filesystem management.

Tokens
43.3K
Snippets
93
Records
123
Agent score
53%

What's inside ImagePickerKMP

  1. Overview of ImagePickerKMP customization options

    develop

    ImagePickerKMP is designed to be highly customizable to match your application's design and user experience requirements. You can customize the library through several mechanisms:

    • Custom UI Components: Replace default dialogs and views with your own implementation.
    • Theme Integration: Align the picker's color scheme and typography with your app's design.
    • Behavior Customization: Control the functional behavior of the picker.
    • Callback Customization: Implement custom logic for handling events.
  2. Understand ImagePickerKMP Core Module capabilities

    develop

    The imagepicker-core module provides the foundational cross-platform abstractions required for the ImagePickerKMP ecosystem. It handles essential low-level operations that feature modules rely on, including:

    • Permissions: Cross-platform permission handling.
    • Filesystem: Shared filesystem abstractions.
    • URI Handling: Standardized URI management.
    • Logging: Shared logging interfaces.
  3. Prerequisites for ImagePickerKMP

    develop

    Before integrating ImagePickerKMP, ensure your environment meets these requirements:

    • Project Type: Kotlin Multiplatform project set up.
    • IDE: Android Studio or IntelliJ IDEA with the Kotlin plugin.
    • iOS Development: Xcode installed.
    • Minimum SDK Versions:
      • Android: API 21+
      • iOS: iOS 12.0+
  4. Internationalization (i18n) in ImagePickerKMP

    develop

    ImagePickerKMP provides automatic translation for UI elements (permissions, camera UI, error feedback, etc.) using the getLanguageDevice() method to detect the user's device language.

    Supported Languages

    Currently supports 14 languages:

    • English (en)
    • Spanish (es)
    • French (fr)
    • Chinese (zh)
    • Korean (ko)
    • Japanese (ja)
    • Hindi (hi)
    • Thai (th)
    • Italian (it)
    • German (de)
    • Russian (ru)
    • Ukrainian (uk)
    • Polish (pl)
    • Dutch (nl)

    Adding a New Language

    To contribute a new language, add your translations to the src/commonMain/resources/translations.yaml file within the specific module you wish to extend.

  5. Use Batch Mode for multiple scans

    develop

    To scan multiple codes before confirming, set batchMode = true in ScannerAdvancedFeaturesConfig.

    While scanning, you can access the live list of accumulated codes via scanner.scannedCodes. When the user finishes (e.g., taps 'Done'), the result is returned as ScannerPickerState.BatchSuccess containing the full list of ScannerResult objects.

    val scanner = rememberScannerPicker(
        config = ScannerPickerConfig(
            camera = ScannerCameraConfig(
                advanced = ScannerAdvancedFeaturesConfig(batchMode = true)
            )
        )
    )
    
    // Access live list while scanning:
    val scanned: List<ScannerResult> = scanner.scannedCodes
    
    // Final result when user taps Done:
    is ScannerPickerState.BatchSuccess -> result.results.forEach { /* ... */ }
  6. Handle user cancellation with ImagePickerResult.Dismissed

    develop

    When a user cancels the selection (e.g., tapping 'Cancel' in the camera interface or the gallery dialog), the library emits ImagePickerResult.Dismissed. This is the standard way to detect and reset your UI state after a user exits the picker without selecting anything.

    // Example of handling dismissal in a Gallery picker
    @Composable
    fun MyGalleryPicker() {
        val picker = rememberImagePickerKMP(
            config = ImagePickerKMPConfig(
                galleryConfig = GalleryConfig(allowMultiple = true)
            )
        )
    
        when (val result = picker.result) {
            is ImagePickerResult.Dismissed -> {
                println("User cancelled gallery selection")
            }
            // ... other states
        }
    
        Button(onClick = { picker.launchGallery(allowMultiple = true) }) {
            Text("Pick from Gallery")
        }
    }
  7. How automatic translations (i18n) work in ImagePickerKMP

    develop

    The library features built-in internationalization (i18n) support. Translations are modularized per feature module (e.g., imagepickerkmp-photo, imagepickerkmp-video) using the i18nKonfig Gradle plugin.

    When using the provided UI components, the library automatically detects the user's device language and displays the corresponding localized strings without requiring manual configuration by the developer.

  8. Manage Camera and Gallery permissions

    develop

    The library utilizes system-level permissions to access device hardware and storage:

    Camera Access

    • Purpose: Required to capture new photos using the device camera.
    • Storage: Captured images are not stored by the library itself.
    • Control: Permission requests are handled transparently via standard system dialogs, allowing users to grant or deny access.
    • Purpose: Required to select existing photos from the device gallery.
    • Data Flow: Selected image content is processed locally and is not transmitted to any external servers.
  9. Understand permission handling behavior in ImagePickerKMP

    develop

    ImagePickerKMP provides a unified permission handling experience that adapts to the native behaviors of Android and iOS. This ensures that the library respects platform-specific UX patterns while providing consistent error handling and user guidance.

    Platform Behaviors

    • Android: The system supports retries. If a permission is denied, the library can present rationale dialogs to explain why the permission is required before allowing the user to attempt the request again.
    • iOS: The system follows native iOS constraints. If a permission is denied for the first time, the library directs the user to the system settings dialog to enable the permission manually.

    Common Features

    • User Guidance: Both platforms provide clear error handling and guidance to help users navigate permission states.
    • Customization: Developers can implement custom dialogs and use callbacks to handle permission results and user interactions.
  10. Handle ImagePickerResult states

    develop

    The picker.result property returns an ImagePickerResult which represents the current state of the picker operation:

    StateWhen
    IdleInitial state, or after reset()
    LoadingPicker is open and waiting for user input
    Success(photos)User selected one or more photos
    DismissedUser cancelled without selecting
    Error(exception)Something went wrong

    Use the following pattern to access results:

    when (val result = picker.result) {
        is ImagePickerResult.Success -> {
            val first: PhotoResult? = result.first   // shortcut for single picks
            val all: List<PhotoResult> = result.photos
        }
        else -> Unit
    }
  11. Customize permission and confirmation UI

    develop

    The PermissionAndConfirmationConfig allows you to inject custom Composable functions to control the user experience when permissions are requested or when a photo needs review.

    Key customization hooks include:

    • customConfirmationView: A Composable that takes the PhotoResult, an onConfirm callback, and an onRetry callback. Use this to show a preview of the captured image before finalizing.
    • customDeniedDialog: A Composable that takes an onRetry callback. Use this to show a custom dialog when a user denies a required permission.
    • customSettingsDialog: A Composable that takes an onOpenSettings callback. Use this to guide users to the system settings when permissions are permanently denied.