### GalleryPickerLauncher Configuration Example Source: https://github.com/ismoy/imagepickerkmp/blob/develop/docs/API_REFERENCE.md Example demonstrating how to configure the `GalleryPickerLauncher` with specific settings for MIME types and Android gallery behavior. ```kotlin GalleryPickerLauncher( config = GalleryPickerConfig( includeExif = true, androidGalleryConfig = AndroidGalleryConfig( forceGalleryOnly = false, localOnly = true ) ), mimeTypes = listOf(MimeType.APPLICATION_PDF), onPhotosSelected = { results -> // Handle selected files } ) ``` -------------------------------- ### CameraPermissionDialogConfig Example Source: https://github.com/ismoy/imagepickerkmp/blob/develop/docs/API_REFERENCE.md An example showing how to instantiate `CameraPermissionDialogConfig` with specific text for permission request and denial dialogs. ```kotlin val dialogConfig = CameraPermissionDialogConfig( titleDialogConfig = "Camera permission required", descriptionDialogConfig = "Camera permission is required to capture photos. Please grant it in settings", btnDialogConfig = "Open settings", titleDialogDenied = "Camera permission denied", descriptionDialogDenied = "Camera permission is required to capture photos. Please grant the permissions", btnDialogDenied = "Grant permission" ) ``` -------------------------------- ### CameraPreviewConfig Example Source: https://github.com/ismoy/imagepickerkmp/blob/develop/docs/API_REFERENCE.md An example demonstrating how to configure the `CameraPreviewConfig` with custom capture button size, UI colors, and camera event callbacks. ```kotlin val cameraPreviewConfig = CameraPreviewConfig( captureButtonSize = 80.dp, uiConfig = UiConfig( buttonColor = Color.Blue, iconColor = Color.White ), cameraCallbacks = CameraCallbacks( onCameraReady = { println("Camera ready") }, onCameraSwitch = { println("Camera switched") } ) ) ``` -------------------------------- ### Comprehensive Error Handling Example Source: https://github.com/ismoy/imagepickerkmp/blob/develop/docs/EXAMPLES.md Demonstrates how to handle various exceptions thrown by the ImagePickerLauncher. This example shows how to differentiate between PhotoCaptureException, CameraPermissionException, and GallerySelectionException. ```kotlin @Composable fun ErrorHandlingExample() { ImagePickerLauncher( context = LocalContext.current, config = ImagePickerConfig( onPhotoCaptured = { result -> /* ... */ }, onError = { exception -> when (exception) { is PhotoCaptureException -> { println("Photo capture failed: ${exception.message}") // Show user-friendly error message } is CameraPermissionException -> { println("Camera permission denied: ${exception.message}") // Handle permission error } is GallerySelectionException -> { println("Gallery selection failed: ${exception.message}") // Handle gallery error } else -> { println("Unknown error: ${exception.message}") // Handle generic error } } } ) ) } ``` -------------------------------- ### Development Setup for ImagePickerKMP Source: https://github.com/ismoy/imagepickerkmp/blob/develop/docs/CHANGELOG.md Provides essential commands for cloning the repository, navigating to the project directory, building the project, and running tests using Gradle. ```bash # Clone the repository git clone https://github.com/ismoy/ImagePickerKMP.git # Navigate to project directory cd ImagePickerKMP # Build the project ./gradlew build # Run tests ./gradlew test ``` -------------------------------- ### Simple Image Cropping Example Source: https://github.com/ismoy/imagepickerkmp/blob/develop/docs/EXAMPLES.md Demonstrates a basic image cropping flow using default options. It allows selecting an image from the gallery and then cropping it. ```kotlin import androidx.compose.foundation.Image import androidx.compose.foundation.layout.* import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Button import androidx.compose.material3.Text import androidx.compose.runtime.* import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.unit.dp import com.example.imagepickerkmp.components.GalleryPickerLauncher import com.example.imagepickerkmp.components.ImageCropView import com.example.imagepickerkmp.utils.toComposeImageBitmap @Composable fun SimpleCropExample() { var showImagePicker by remember { mutableStateOf(false) } var selectedImage by remember { mutableStateStateOf(null) } var showCropView by remember { mutableStateOf(false) } var croppedImageBytes by remember { mutableStateOf(null) } Column( modifier = Modifier .fillMaxSize() .padding(16.dp) ) { Button( onClick = { showImagePicker = true }, modifier = Modifier.fillMaxWidth() ) { Text("Select Image to Crop") } selectedImage?.let { imageBytes -> Spacer(modifier = Modifier.height(16.dp)) Text("Original Image:") Image( bitmap = imageBytes.toComposeImageBitmap(), contentDescription = "Original image", modifier = Modifier .fillMaxWidth() .height(200.dp) .clip(RoundedCornerShape(8.dp)), contentScale = ContentScale.Crop ) Button( onClick = { showCropView = true }, modifier = Modifier.fillMaxWidth() ) { Text("Crop Image") } } croppedImageBytes?.let { croppedBytes -> Spacer(modifier = Modifier.height(16.dp)) Text("Cropped Image:") Image( bitmap = croppedBytes.toComposeImageBitmap(), contentDescription = "Cropped image", modifier = Modifier .fillMaxWidth() .height(200.dp) .clip(RoundedCornerShape(8.dp)), contentScale = ContentScale.Crop ) } } if (showImagePicker) { GalleryPickerLauncher( onPhotosSelected = { photos -> photos.firstOrNull()?.let { photo -> selectedImage = photo.photoBytes } showImagePicker = false }, onError = { showImagePicker = false }, onDismiss = { showImagePicker = false }, allowMultiple = false ) } if (showCropView && selectedImage != null) { ImageCropView( originalImageBytes = selectedImage!!, onCropComplete = { croppedBytes -> croppedImageBytes = croppedBytes showCropView = false }, onDismiss = { showCropView = false } ) } } ``` -------------------------------- ### Android Camera Permission Request Example Source: https://github.com/ismoy/imagepickerkmp/blob/develop/library/PERMISSION.md Demonstrates launching a camera permission request on Android and handling the result. ```kotlin // Example: Requesting camera permission in Android val permissionLauncher = rememberLauncherForActivityResult( contract = ActivityResultContracts.RequestPermission() ) { if (isGranted) { // Permission granted - proceed with camera startCamera() } else { // Permission denied - show retry dialog showPermissionDialog() } } // Launch permission request permissionLauncher.launch(Manifest.permission.CAMERA) ``` -------------------------------- ### Basic Image Picker Usage Source: https://github.com/ismoy/imagepickerkmp/blob/develop/docs/ImagePickerLauncher_Documentation.md Demonstrates the fundamental setup for ImagePickerLauncher to capture a single photo. It requires a context and a configuration block to handle the captured photo or errors. ```kotlin @Composable fun MyImagePicker() { ImagePickerLauncher( context = LocalContext.current, config = ImagePickerConfig( onPhotoCaptured = { result -> // Handle captured photo println("Photo captured: ${result.uri}") }, onError = { exception -> // Handle error println("Error: ${exception.message}") } ) ) } ``` -------------------------------- ### CustomPermissionHandler Example Source: https://github.com/ismoy/imagepickerkmp/blob/develop/docs/API_REFERENCE.md An example composable demonstrating how to use the RequestCameraPermission function with a custom permission handler configuration. ```kotlin @Composable fun CustomPermissionHandler() { val dialogConfig = CameraPermissionDialogConfig( titleDialogConfig = "Camera permission required", descriptionDialogConfig = "Please enable camera access in settings", btnDialogConfig = "Open settings", titleDialogDenied = "Permission denied", descriptionDialogDenied = "Camera permission is required", btnDialogDenied = "Grant permission" ) RequestCameraPermission( dialogConfig = dialogConfig, onPermissionPermanentlyDenied = { println("Permission permanently denied") }, onResult = { granted -> println("Permission granted: $granted") }, customPermissionHandler = null ) } ``` -------------------------------- ### Basic Image Loading with Camera and Gallery Source: https://github.com/ismoy/imagepickerkmp/blob/develop/docs/EXAMPLES.md Demonstrates how to launch the camera and gallery pickers and load the selected image data as a ByteArray. This example requires no additional configuration for loading bytes. ```kotlin import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.padding import androidx.compose.material3.Button import androidx.compose.material3.Text import androidx.compose.runtime.* import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import com.github.drjacky.imageutil.ImagePickerConfig import com.github.drjacky.imageutil.ImagePickerLauncher import com.github.drjacky.imageutil.PhotoResult import com.github.drjacky.imageutil.GalleryPickerConfig import com.github.drjacky.imageutil.GalleryPhotoResult @Composable fun ByteArrayExample() { var photoResult by remember { mutableStateOf(null) } var galleryResult by remember { mutableStateStateOf(null) } var imageBytes by remember { mutableStateOf(null) } Column(modifier = Modifier.padding(16.dp)) { // Camera capture ImagePickerLauncher( config = ImagePickerConfig( onPhotoCaptured = { result -> photoResult = result } ) ) // Gallery selection GalleryPickerLauncher( config = GalleryPickerConfig( onPhotoSelected = { result -> galleryResult = result } ) ) // Load bytes from camera result - Zero config! photoResult?.let { photo -> Button( onClick = { // Just works - no setup required! imageBytes = photo.loadBytes() } ) { Text("Load Camera Photo as ByteArray") } } // Load bytes from gallery result - Zero config! galleryResult?.let { gallery -> Button( onClick = { // Just works - no setup required! imageBytes = gallery.loadBytes() } ) { Text("Load Gallery Photo as ByteArray") } } // Display byte array info imageBytes?.let { bytes -> Text("Image loaded: ${bytes.size} bytes") } } } ``` -------------------------------- ### iOS Camera Permission Request Example Source: https://github.com/ismoy/imagepickerkmp/blob/develop/library/PERMISSION.md Demonstrates requesting camera access on iOS and handling the authorization status. ```swift // Example: Requesting camera permission in iOS fun requestCameraAccess(callback: (Boolean) -> Unit) { AVCaptureDevice.requestAccessForMediaType(AVMediaTypeVideo) { granted -> callback(granted) } } // Check current permission status val status = AVCaptureDevice.authorizationStatusForMediaType(AVMediaTypeVideo) when (status) { AVAuthorizationStatusAuthorized -> { // Permission already granted startCamera() } AVAuthorizationStatusNotDetermined -> { // Request permission requestCameraAccess { granted -> if (granted) { startCamera() } else { showSettingsDialog() } } } AVAuthorizationStatusDenied, AVAuthorizationStatusRestricted -> { // Permission denied - show settings dialog showSettingsDialog() } } ``` -------------------------------- ### Confirmation Image Scale Examples Source: https://github.com/ismoy/imagepickerkmp/blob/develop/docs/API_REFERENCE.md Illustrates different ContentScale options for the confirmation image preview within PermissionAndConfirmationConfig. Choose how the captured photo is scaled in the confirmation screen. ```kotlin // Default — crop to fill the preview area PermissionAndConfirmationConfig() ``` ```kotlin // Fit — show the entire photo letterboxed PermissionAndConfirmationConfig( confirmationImageContentScale = ContentScale.Fit ) ``` ```kotlin // Fill width PermissionAndConfirmationConfig( confirmationImageContentScale = ContentScale.FillWidth ) ``` -------------------------------- ### Test Camera Permission Flow Source: https://github.com/ismoy/imagepickerkmp/blob/develop/docs/EXAMPLES.md Demonstrates how to test the camera permission request flow. This example shows how to trigger the permission request and handle the results, including permanent denial. ```kotlin // Ejemplo de prueba del flujo de permisos @Composable fun TestPermissionFlow() { var showPermissionTest by remember { mutableStateOf(false) } if (showPermissionTest) { RequestCameraPermission( titleDialogConfig = "Camera Permission Required", descriptionDialogConfig = "Please enable camera access in settings", btnDialogConfig = "Open Settings", titleDialogDenied = "Permission Denied", descriptionDialogDenied = "Camera permission is required. Please try again.", btnDialogDenied = "Try Again", onPermissionPermanentlyDenied = { println("Permission permanently denied - should show settings dialog") }, onResult = { println("Permission result: $granted") showPermissionTest = false } ) } Button(onClick = { showPermissionTest = true }) { Text("Test Permission Flow") } } ``` -------------------------------- ### Permission Denied Error Handling Example Source: https://github.com/ismoy/imagepickerkmp/blob/develop/docs/API_REFERENCE.md A try-catch block demonstrating how to catch a PermissionDeniedException when requesting permissions. ```kotlin try { requestCameraPermission() } catch (e: PermissionDeniedException) { println("Permissions denied: ${e.message}") } ``` -------------------------------- ### Image Processing Workflow Example Source: https://github.com/ismoy/imagepickerkmp/blob/develop/docs/ImageProcessor_Documentation.md Demonstrates a typical sequence of image processing operations: initial processing, orientation correction, and resizing. Ensure exceptions are handled when using these methods. ```kotlin val processed = ImageProcessor.processImage(rawImage) val rotated = ImageProcessor.correctImageOrientation(processed, orientation) val resized = ImageProcessor.resizeImage(rotated, 1024, 768) ``` -------------------------------- ### Discord Message Format Example Source: https://github.com/ismoy/imagepickerkmp/blob/develop/docs/NOTIFICATIONS_SETUP.md This is an example of a Discord message format used for build success notifications, including repository details, coverage reports, and workflow information. ```text 🎉 ImagePickerKMP Build Success Repository: ismoy/ImagePickerKMP Branch: main Commit: abc123... Triggered by: username 📊 Coverage Report: • Line Coverage: 45.2% • Branch Coverage: 32.1% Duration: 120s Workflow: CI 🔗 View Details: https://github.com/... ``` -------------------------------- ### Image Picker Result Handling with Path Extensions Source: https://github.com/ismoy/imagepickerkmp/blob/develop/docs/API_REFERENCE.md Example demonstrating how to handle image picker results and access file paths using `toPath()` and `absolutePath` extensions. ```kotlin val picker = rememberImagePickerKMP() when (val result = picker.result) { is ImagePickerResult.Success -> { result.first?.let { photo -> // Using kotlinx.io Path (cross-platform, v1.0.38+) photo.toPath()?.let { path -> println("File path: $path") // Use kotlinx-io file operations } // Using absolute path String (platform-specific, v1.0.40+) photo.absolutePath?.let { path -> println("Absolute path: $path") } } } else -> {} } ``` -------------------------------- ### Image Picker with EXIF Data Source: https://github.com/ismoy/imagepickerkmp/blob/develop/docs/API_REFERENCE.md Example of launching an image picker with EXIF data enabled. The `onPhotoCaptured` callback processes the result, and `cameraCaptureConfig` is set to include EXIF. ```kotlin ImagePickerLauncher( config = ImagePickerConfig( onPhotoCaptured = { result -> result.exif?.let { exif -> println(" GPS: ${exif.latitude}, ${exif.longitude}") println(" Camera: ${exif.cameraModel}") println(" Date: ${exif.dateTaken}") println(" Settings: ISO ${exif.iso}, f/${exif.aperture}") } }, cameraCaptureConfig = CameraCaptureConfig( includeExif = true ) ) ) ``` -------------------------------- ### Camera Scale Type Examples Source: https://github.com/ismoy/imagepickerkmp/blob/develop/docs/API_REFERENCE.md Demonstrates different ways to configure the camera scale type within CameraCaptureConfig. Use these to control how the camera preview is scaled within its viewport. ```kotlin // Default — fills the viewport, crops the feed to fit CameraCaptureConfig() ``` ```kotlin // Letterbox — full camera feed visible, matches captured image framing CameraCaptureConfig( cameraScaleType = CameraScaleType.FIT_CENTER ) ``` ```kotlin // Fill from top-left CameraCaptureConfig( cameraScaleType = CameraScaleType.FILL_START ) ``` -------------------------------- ### HTML Setup for ImagePickerKMP Bundle Source: https://github.com/ismoy/imagepickerkmp/blob/develop/REACT_INTEGRATION_GUIDE.md Include the ImagePickerKMP-bundle.js script in your index.html file before your React application loads. This makes the library's functionality available globally. ```html Your React App
``` -------------------------------- ### Custom Permission Dialogs Example Source: https://github.com/ismoy/imagepickerkmp/blob/develop/docs/EXAMPLES.md This composable function demonstrates how to use ImagePickerLauncher with custom dialogs for camera permission requests. It shows how to define custom composables for when the camera permission is denied and when it is permanently denied, allowing for a more user-friendly permission flow. ```kotlin import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Button import androidx.compose.material3.Card import androidx.compose.material3.Dialog import androidx.compose.material3.Text import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.github.drjacky.imageview.ImagePickerLauncher import com.github.drjacky.imageview.config.CameraCaptureConfig import com.github.drjacky.imageview.config.ImagePickerConfig import com.github.drjacky.imageview.config.PermissionAndConfirmationConfig @Composable fun CustomPermissionDialogsExample() { var showPicker by remember { mutableStateOf(false) } if (showPicker) { ImagePickerLauncher( config = ImagePickerConfig( onPhotoCaptured = { result -> showPicker = false }, onError = { showPicker = false }, onDismiss = { showPicker = false }, cameraCaptureConfig = CameraCaptureConfig( permissionAndConfirmationConfig = PermissionAndConfirmationConfig( // Custom dialog when permission is denied customDeniedDialog = { onRetry -> CustomRetryDialog( title = "Camera Permission Needed", message = "We need camera access to take photos", onRetry = onRetry ) }, // Custom dialog when permission is permanently denied customSettingsDialog = { onOpenSettings -> CustomSettingsDialog( title = "Open Settings", message = "Please enable camera permission in Settings", onOpenSettings = onOpenSettings ) } ) ) ) ) } Button(onClick = { showPicker = true }) { Text("Take Photo with Custom Permission Dialogs") } } @Composable fun CustomRetryDialog( title: String, message: String, onRetry: () -> Unit ) { Dialog(onDismissRequest = { }) { Card( modifier = Modifier.fillMaxWidth().padding(16.dp), shape = RoundedCornerShape(16.dp) ) { Column( modifier = Modifier.padding(24.dp), horizontalAlignment = Alignment.CenterHorizontally ) { Text( text = "📸", fontSize = 48.sp, modifier = Modifier.padding(bottom = 16.dp) ) Text( text = title, fontSize = 20.sp, fontWeight = FontWeight.Bold, textAlign = TextAlign.Center, modifier = Modifier.padding(bottom = 12.dp) ) Text( text = message, fontSize = 16.sp, textAlign = TextAlign.Center, color = Color.Gray, modifier = Modifier.padding(bottom = 24.dp) ) Button( onClick = onRetry, modifier = Modifier.fillMaxWidth() ) { Text("Grant Permission") } } } } } @Composable fun CustomSettingsDialog( title: String, message: String, onOpenSettings: () -> Unit ) { Dialog(onDismissRequest = { }) { Card( modifier = Modifier.fillMaxWidth().padding(16.dp), shape = RoundedCornerShape(16.dp) ) { Column( modifier = Modifier.padding(24.dp), horizontalAlignment = Alignment.CenterHorizontally ) { Text( text = "⚙️", fontSize = 48.sp, modifier = Modifier.padding(bottom = 16.dp) ) Text( text = title, fontSize = 20.sp, fontWeight = FontWeight.Bold, textAlign = TextAlign.Center, modifier = Modifier.padding(bottom = 12.dp) ) Text( text = message, fontSize = 16.sp, textAlign = TextAlign.Center, color = Color.Gray, modifier = Modifier.padding(bottom = 24.dp) ) Button( onClick = onOpenSettings, modifier = Modifier.fillMaxWidth() ) { Text("Open Settings") } } } } } ``` -------------------------------- ### Custom Image Picker with Camera Capture Source: https://github.com/ismoy/imagepickerkmp/blob/develop/docs/EXAMPLES.md Shows how to create a custom image picker using ImagePickerLauncher, including configuration for camera capture preferences and custom permission/confirmation handlers. This example uses LocalContext.current for the Android context. ```kotlin @Composable fun CustomImagePicker() { var showPicker by remember { mutableStateOf(false) } if (showPicker) { ImagePickerLauncher( context = LocalContext.current, config = ImagePickerConfig( onPhotoCaptured = { result -> showPicker = false }, onError = { exception -> showPicker = false }, cameraCaptureConfig = CameraCaptureConfig( preference = CapturePhotoPreference.HIGH_QUALITY, permissionAndConfirmationConfig = PermissionAndConfirmationConfig( customPermissionHandler = { config -> // Custom permission handling }, customConfirmationView = { result, onConfirm, onRetry -> // Custom confirmation view } ) ) ) ) } Button(onClick = { showPicker = true }) { Text("Take Photo") } } ``` -------------------------------- ### iOS Permissions Setup in Info.plist Source: https://github.com/ismoy/imagepickerkmp/blob/develop/README.md Add necessary keys to your iOS Info.plist file to request camera and photo library access. This is required for the app to function correctly on iOS. ```xml NSCameraUsageDescription Camera access needed to take photos NSPhotoLibraryUsageDescription Photo library access needed to select images ``` -------------------------------- ### Shared Module App Example Source: https://github.com/ismoy/imagepickerkmp/blob/develop/docs/EXAMPLES.md Illustrates how the CameraScreen component can be used in a shared module, working seamlessly on both Android and iOS. The library manages platform-specific context handling internally. ```kotlin // App.kt (shared module) @Composable fun ImagePickerApp() { MaterialTheme { Surface( modifier = Modifier.fillMaxSize(), color = MaterialTheme.colors.background ) { // The same component works on both platforms // The library handles platform differences internally CameraScreen(context = null) // Context will be provided by the platform-specific app } } } ``` -------------------------------- ### High-Performance Gallery Selection with Limit Source: https://github.com/ismoy/imagepickerkmp/blob/develop/docs/EXAMPLES.md Optimizes gallery selection by setting a conservative `selectionLimit` (e.g., 5) for potentially better performance. This example demonstrates selecting up to 5 images. ```kotlin import androidx.compose.runtime.* import androidx.compose.ui.platform.LocalContext import androidx.compose.material.Button import androidx.compose.material.Text @Composable fun HighPerformanceGalleryExample() { var showGallery by remember { mutableStateOf(false) } if (showGallery) { ImagePickerLauncher( context = LocalContext.current, config = ImagePickerConfig( onPhotoCaptured = { result -> showGallery = false }, onPhotosSelected = { results -> showGallery = false }, onError = { exception -> showGallery = false }, cameraCaptureConfig = CameraCaptureConfig( galleryConfig = GalleryConfig( allowMultiple = true, selectionLimit = 5 // Conservative limit for better performance ) ) ) ) } Button(onClick = { showGallery = true }) { Text("Select Up to 5 Images (Optimized)") } } ``` -------------------------------- ### Configure Minimum Line Coverage Threshold Source: https://github.com/ismoy/imagepickerkmp/blob/develop/docs/COVERAGE_GUIDE.md Example of how to set the minimum line coverage threshold in a Gradle build script. Adjust the BigDecimal value to set the desired percentage. ```kotlin minimum = "0.10".toBigDecimal() // 10% line coverage ``` -------------------------------- ### Gallery Picker with EXIF Data Source: https://github.com/ismoy/imagepickerkmp/blob/develop/docs/API_REFERENCE.md Example of launching a gallery picker to select photos with EXIF data. The `onPhotosSelected` callback iterates through results, printing EXIF details or a message if none are available. Multiple selections are allowed, and EXIF inclusion is explicitly enabled. ```kotlin GalleryPickerLauncher( onPhotosSelected = { results -> results.forEachIndexed { index, result -> println("Image $index:") result.exif?.let { exif -> println(" Location: ${exif.latitude}, ${exif.longitude}") println(" Camera: ${exif.cameraModel}") println(" Date: ${exif.dateTaken}") } ?: println(" No EXIF data available") } }, allowMultiple = true, includeExif = true ) ``` -------------------------------- ### React/JavaScript Dependency Installation Source: https://github.com/ismoy/imagepickerkmp/blob/develop/README.md Install the imagepickerkmp package using npm for your React or JavaScript projects. ```bash npm install imagepickerkmp ``` -------------------------------- ### Install Material-UI Styling Dependencies Source: https://github.com/ismoy/imagepickerkmp/blob/develop/REACT_INTEGRATION_GUIDE.md Install the required peer dependencies for Material-UI styling, including Material-UI components, icons, and react-toastify for notifications. ```bash npm install @mui/material @mui/icons-material react-toastify ``` -------------------------------- ### iOS ImagePickerKMP Pod Installation Source: https://github.com/ismoy/imagepickerkmp/blob/develop/docs/FAQ.md Add ImagePickerKMP to your iOS project using CocoaPods by specifying the path in your Podfile and running 'pod install'. ```ruby # Podfile target 'YourApp' do use_frameworks! pod 'ImagePickerKMP', :path => '../path/to/your/library' end ``` ```bash pod install ``` ```swift import ImagePickerKMP ``` -------------------------------- ### Launch Gallery (v2 API) Source: https://github.com/ismoy/imagepickerkmp/blob/develop/docs/API_REFERENCE.md Use `picker.launchGallery()` for new code. This replaces the legacy `GalleryPickerLauncher`. ```kotlin picker.launchGallery() ``` -------------------------------- ### Launch Camera with Custom Confirmation and Permissions Source: https://github.com/ismoy/imagepickerkmp/blob/develop/docs/INTEGRATION_GUIDE.md This snippet demonstrates how to launch the camera using ImagePickerLauncher. It includes custom views for confirmation and permission handling, including denied and settings dialogs. ```kotlin var showCameraPicker by remember { mutableStateOf(false) } var photoResult by remember { mutableStateOf(null) } var isPickerSheetVisible by remember { mutableStateOf(false) } Scaffold { innerPadding -> Column( modifier = Modifier .padding(innerPadding) .fillMaxSize() ) { Box( modifier = Modifier .fillMaxWidth() .weight(1f), contentAlignment = Alignment.Center ) { when { showCameraPicker -> { ImagePickerLauncher( config = ImagePickerConfig( onPhotoCaptured = { result -> photoResult = result showCameraPicker = false isPickerSheetVisible = false }, onError = { showCameraPicker = false isPickerSheetVisible = false }, onDismiss = { showCameraPicker = false isPickerSheetVisible = false }, cameraCaptureConfig = CameraCaptureConfig( permissionAndConfirmationConfig = PermissionAndConfirmationConfig( customConfirmationView = { photoResult, onConfirm, onRetry -> CustomAndroidConfirmationView( result = photoResult, onConfirm = onConfirm, onRetry = onRetry ) }, customDeniedDialog = { onRetry -> CustomPermissionDialog( title = "Permission Required", message = "We need access to the camera to take photos", onRetry = onRetry ) }, customSettingsDialog = { onOpenSettings -> CustomPermissionSettingsDialog( title = "Go to Settings", message = "Camera permission is required to capture photos. Please grant it in settings", onOpenSettings = onOpenSettings ) } ) ) ) ) } photoResult != null -> { Card( shape = RoundedCornerShape(16.dp), elevation = 8.dp, modifier = Modifier .fillMaxSize() .padding(8.dp) ) { AsyncImage( model = cameraPhoto?.uri, contentDescription = "Captured photo", modifier = Modifier.fillMaxSize() ) } } else -> { Text("No image selected", color = Color.Gray) } } } if (!isPickerSheetVisible) { Column( modifier = Modifier .fillMaxWidth() .padding(bottom = 32.dp), horizontalAlignment = Alignment.CenterHorizontally ) { OutlinedButton( onClick = { selectedImages = emptyList() cameraPhoto = null showCameraPicker = true }, modifier = Modifier .fillMaxWidth() .padding(horizontal = 16.dp) ) { Text("Open Camera") } Spacer(modifier = Modifier.height(8.dp)) } } } } ``` -------------------------------- ### Kotlin Multiplatform Dependency Installation Source: https://github.com/ismoy/imagepickerkmp/blob/develop/README.md Add this dependency to your Kotlin Multiplatform project to integrate ImagePickerKMP. ```kotlin dependencies { implementation("io.github.ismoy:imagepickerkmp:1.0.41") } ``` -------------------------------- ### Build and Test Project Source: https://github.com/ismoy/imagepickerkmp/blob/develop/docs/CONTRIBUTING.md Commands to compile the project, run various types of tests, and perform static analysis. ```bash # Compile the project ./gradlew build # Run unit tests (JVM — fast, no emulator needed) ./gradlew :library:jvmTest # Run Android unit tests ./gradlew :library:testDebugUnitTest # Run all tests ./gradlew :library:allTests # Run static analysis ./gradlew detekt ``` -------------------------------- ### Photo Capture Error Handling Example Source: https://github.com/ismoy/imagepickerkmp/blob/develop/docs/API_REFERENCE.md A try-catch block demonstrating how to catch a PhotoCaptureException when capturing a photo. ```kotlin try { capturePhoto() } catch (e: PhotoCaptureException) { println("Error capturing photo: ${e.message}") } ``` -------------------------------- ### iOS Provide Clear Instructions Source: https://github.com/ismoy/imagepickerkmp/blob/develop/library/PERMISSION.md Provides clear instructions on iOS for users to enable camera access in the app's privacy settings. ```kotlin // Clear instructions for settings description = "Please go to Settings > Privacy & Security > Camera and enable access for this app" ``` -------------------------------- ### CustomLogger Implementation Source: https://github.com/ismoy/imagepickerkmp/blob/develop/docs/API_REFERENCE.md An example of a custom logger implementation for ImagePickerLogger, using Android's Log class. ```kotlin class CustomLogger : ImagePickerLogger { override fun log(message: String) { Log.d("ImagePicker", message) } } ``` -------------------------------- ### Implement Camera Screen with ImagePickerLauncher Source: https://github.com/ismoy/imagepickerkmp/blob/develop/docs/EXAMPLES.md This composable function sets up a screen with a button to open the camera and displays the captured image. It uses ImagePickerLauncher to handle the photo capture process. ```kotlin package io.github.ismoy.belzspeedscan.core.camera.ui import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.material.ButtonDefaults import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.OutlinedButton import androidx.compose.material.Scaffold import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp import coil3.compose.AsyncImage import io.github.ismoy.imagepickerkmp.CameraPhotoHandler import io.github.ismoy.imagepickerkmp.CapturePhotoPreference import io.github.ismoy.imagepickerkmp.ImagePickerLauncher @OptIn(ExperimentalMaterialApi::class) @Composable fun CameraScreen(context: Any?) { var showImagePicker by remember { mutableStateOf(false) } var capturedImage by remember { mutableStateOf(null) } Scaffold { innerPadding -> Column( modifier = Modifier .padding(innerPadding) .fillMaxSize() ) { Box( modifier = Modifier .fillMaxWidth() .weight(1f), contentAlignment = Alignment.Center ) { if (showImagePicker) { ImagePickerLauncher( context = context, config = ImagePickerConfig( onPhotoCaptured = { photoResult -> capturedImage = photoResult showImagePicker = false }, onError = { exception -> showImagePicker = false }, preference = CapturePhotoPreference.QUALITY ) ) } else if (capturedImage != null) { AsyncImage( model = capturedImage?.uri, contentDescription = "Imagen capturada", modifier = Modifier .fillMaxSize() ) } } Column( modifier = Modifier .fillMaxWidth() .padding(bottom = 32.dp), horizontalAlignment = Alignment.CenterHorizontally ) { OutlinedButton( onClick = { showImagePicker = true }, modifier = Modifier .fillMaxWidth() .padding(horizontal = 16.dp) ) { Text("Open Camera") } Spacer(modifier = Modifier.height(8.dp)) } } } } ``` -------------------------------- ### Android MainActivity Setup for Compose Source: https://github.com/ismoy/imagepickerkmp/blob/develop/docs/EXAMPLES.md Configure your MainActivity to use Jetpack Compose by setting the content view to your ImagePickerApp composable. ```kotlin // MainActivity.kt class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { ImagePickerApp() } } } ``` -------------------------------- ### Enhance Gallery Picker Launcher with Compression Source: https://github.com/ismoy/imagepickerkmp/blob/develop/docs/CHANGELOG.md The `GalleryPickerLauncher` can now support image compression by passing a `CameraCaptureConfig` that includes a `compressionLevel`. ```kotlin val galleryLauncher = GalleryPickerLauncher( ..., cameraCaptureConfig = CameraCaptureConfig(compressionLevel = CompressionLevel.MEDIUM) ) ``` -------------------------------- ### Custom Coverage Threshold Alert Example Source: https://github.com/ismoy/imagepickerkmp/blob/develop/docs/NOTIFICATIONS_SETUP.md This expression can be used within a workflow to trigger a low coverage alert if the line coverage is below 30%. ```yaml ${{ steps.coverage.outputs.line_coverage < 30 && '⚠️ **Low Coverage Alert!**' || '' }} ``` -------------------------------- ### Basic Image Picker Implementation Source: https://github.com/ismoy/imagepickerkmp/blob/develop/docs/FAQ.md Launch the image picker and handle photo capture results, errors, or dismissal using the ImagePickerLauncher composable. ```kotlin @Composable fun MyImagePicker() { var showImagePicker by remember { mutableStateOf(false) } if (showImagePicker) { ImagePickerLauncher( config = ImagePickerConfig( onPhotoCaptured = { result -> println("Photo captured: ${result.uri}") showImagePicker = false }, onError = { exception -> println("Error: ${exception.message}") showImagePicker = false }, onDismiss = { println("User cancelled or dismissed the picker") showImagePicker = false // Reset state when user doesn't select anything } ) ) } Button(onClick = { showImagePicker = true }) { Text("Take Photo") } } ``` -------------------------------- ### Enable High Compression for Gallery Selection Source: https://github.com/ismoy/imagepickerkmp/blob/develop/docs/INTEGRATION_GUIDE.md Set up the GalleryPickerLauncher to use high compression for selected photos. This is useful when minimizing file size is a priority, such as for storage optimization. ```kotlin GalleryPickerLauncher( onPhotosSelected = { photos -> selectedImages = photos showGalleryPicker = false }, onError = { showGalleryPicker = false }, onDismiss = { showGalleryPicker = false }, allowMultiple = true, mimeTypes = listOf(MimeType.IMAGE_JPEG, MimeType.IMAGE_PNG), cameraCaptureConfig = CameraCaptureConfig( compressionLevel = CompressionLevel.HIGH // Optimize for storage ) ) ``` -------------------------------- ### Get Absolute File Path from PhotoResult Source: https://github.com/ismoy/imagepickerkmp/blob/develop/docs/API_REFERENCE.md Retrieves the absolute file system path as a String. Available since v1.0.40. Uses platform-specific implementations. ```kotlin // Get absolute file system path as String (v1.0.40+) val absolutePath: String? = photoResult.absolutePath ``` -------------------------------- ### Configure Image Compression Level Source: https://github.com/ismoy/imagepickerkmp/blob/develop/README.md Set the compression level for camera captures. Options include LOW, MEDIUM, and HIGH. This configuration is part of the ImagePickerLauncher setup. ```kotlin ImagePickerLauncher( config = ImagePickerConfig( cameraCaptureConfig = CameraCaptureConfig( compressionLevel = CompressionLevel.HIGH, // LOW, MEDIUM, HIGH skipConfirmation = true ) ) ) ``` -------------------------------- ### Custom Error Messages Example Source: https://github.com/ismoy/imagepickerkmp/blob/develop/docs/EXAMPLES.md Shows how to provide custom, localized error messages based on the type of exception encountered. It uses `getStringResource` with predefined `StringResource` constants. ```kotlin @Composable fun CustomErrorMessagesExample() { ImagePickerLauncher( context = LocalContext.current, config = ImagePickerConfig( onPhotoCaptured = { result -> /* ... */ }, onError = { exception -> val errorMessage = when (exception) { is PhotoCaptureException -> getStringResource(StringResource.PHOTO_CAPTURE_ERROR) is CameraPermissionException -> getStringResource(StringResource.PERMISSION_ERROR) is GallerySelectionException -> getStringResource(StringResource.GALLERY_SELECTION_ERROR) else -> getStringResource(StringResource.INVALID_CONTEXT_ERROR) } // Show localized error message println("Error: $errorMessage") } ) ) } ``` -------------------------------- ### Launch Camera (v2 API) Source: https://github.com/ismoy/imagepickerkmp/blob/develop/docs/API_REFERENCE.md Use `picker.launchCamera()` for new code. This replaces the legacy `ImagePickerLauncher`. ```kotlin picker.launchCamera() ``` -------------------------------- ### Correct Usage of ImagePickerLauncher Source: https://github.com/ismoy/imagepickerkmp/blob/develop/README.md Shows the correct way to use `ImagePickerLauncher` by wrapping it inside a visible container composable like `Box`. This ensures the camera preview is displayed correctly. Incorrect usage can lead to the camera indicator showing without a preview. ```kotlin Box(modifier = Modifier.fillMaxSize()) { if (showCamera) { ImagePickerLauncher( config = ImagePickerConfig( onPhotoCaptured = { /* handle image */ }, onDismiss = { showCamera = false } ) ) } } ``` -------------------------------- ### Skip Camera Confirmation Screen (Android) Source: https://github.com/ismoy/imagepickerkmp/blob/develop/docs/API_REFERENCE.md This example demonstrates how to configure the ImagePickerLauncher to automatically skip the confirmation screen after a photo is captured on Android. The photo is processed immediately. ```kotlin ImagePickerLauncher( config = ImagePickerConfig( onPhotoCaptured = { result -> // Photo is captured automatically without confirmation cameraPhoto = result showCameraPicker = false }, onError = { exception -> // Handle errors showCameraPicker = false }, onDismiss = { // Handle cancellation showCameraPicker = false }, // Configuration to skip confirmation cameraCaptureConfig = CameraCaptureConfig( preference = CapturePhotoPreference.QUALITY, permissionAndConfirmationConfig = PermissionAndConfirmationConfig( skipConfirmation = true // NEW! Skips the confirmation screen ) ) ) ) ``` -------------------------------- ### Customized Image Picker Source: https://github.com/ismoy/imagepickerkmp/blob/develop/docs/ImagePickerLauncher_Documentation.md Shows how to customize the ImagePickerLauncher with various options like preference, colors, multiple selections, and MIME types. This allows for a tailored user experience. ```kotlin @Composable fun CustomImagePicker() { ImagePickerLauncher( context = LocalContext.current, onPhotoCaptured = { result -> // Handle captured photo }, onPhotosSelected = { results -> // Handle multiple selected photos }, onError = { exception -> // Handle error }, preference = CapturePhotoPreference.QUALITY, buttonColor = Color.Blue, iconColor = Color.White, allowMultiple = true, mimeTypes = listOf("image/jpeg", "image/png") ) } ``` -------------------------------- ### Complete Custom Image Picker Implementation Source: https://github.com/ismoy/imagepickerkmp/blob/develop/docs/CUSTOMIZATION_GUIDE.md Demonstrates a full customization of the Image Picker, including custom permission handling and confirmation views. Use this when you need complete control over the picker's UI and behavior. ```kotlin import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.width import androidx.compose.material.Button import androidx.compose.material.ButtonDefaults import androidx.compose.material.Icon import androidx.compose.material.MaterialTheme import androidx.compose.material.Text import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Camera import androidx.compose.runtime.* import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.unit.dp import com.github.terrakok.android.image2picture.CapturePhotoPreference import com.github.terrakok.android.image2picture.ImagePickerLauncher @Composable fun CompleteCustomImagePicker() { var showPicker by remember { mutableStateOf(false) } if (showPicker) { ImagePickerLauncher( context = LocalContext.current, onPhotoCaptured = { result -> // Handle successful photo capture showPicker = false processAndSavePhoto(result) }, onError = { exception -> // Handle errors showPicker = false showErrorDialog(exception) }, customPermissionHandler = { config -> // Custom permission handling CustomPermissionDialog( title = config.titleDialogConfig, description = config.descriptionDialogConfig, onConfirm = { requestPermission() }, onDismiss = { showPicker = false } ) }, customConfirmationView = { result, onConfirm, onRetry -> // Custom confirmation view CustomConfirmationView( result = result, onConfirm = { onConfirm(result) }, onRetry = { onRetry() } ) }, preference = CapturePhotoPreference.HIGH_QUALITY ) } Button( onClick = { showPicker = true }, colors = ButtonDefaults.buttonColors( backgroundColor = MaterialTheme.colors.primary ) ) { Icon(Icons.Default.Camera, "Camera") Spacer(modifier = Modifier.width(8.dp)) Text("Take Photo") } } ``` -------------------------------- ### Conditional Discord Notifications in GitHub Actions Source: https://github.com/ismoy/imagepickerkmp/blob/develop/docs/NOTIFICATIONS_SETUP.md Implement conditional notifications by adding an 'if' statement to the workflow step. This example sends notifications only when the build is on the 'main' branch. ```yaml - name: Notify on Main Branch Only if: github.ref == 'refs/heads/main' uses: Ilshidur/action-discord@master # ... notification config ``` -------------------------------- ### Customizing Discord Notification Messages Source: https://github.com/ismoy/imagepickerkmp/blob/develop/docs/NOTIFICATIONS_SETUP.md Customize the notification text by modifying the 'args' field in the GitHub Actions workflow. This example includes project name and build status. ```yaml args: | 🚀 **Custom Build Success Message** **Project:** ImagePickerKMP **Status:** ${{ github.event.workflow_run.conclusion }} Your custom message here... ``` -------------------------------- ### Initialize and Check ImagePickerKMP in JavaScript Source: https://github.com/ismoy/imagepickerkmp/blob/develop/REACT_INTEGRATION_GUIDE.md This snippet shows how to load the ImagePickerKMP bundle and verify its availability in the global scope. It logs the loaded modules or an error if the library is not found. ```javascript // Load ImagePickerKMP bundle // Check if ImagePickerKMP is loaded if (window.ImagePickerKMP) { console.log(' ImagePickerKMP loaded:', Object.keys(window.ImagePickerKMP)); } else { console.error(' ImagePickerKMP NOT loaded'); } ```