
Modern image cropper with stretchable/resizable selection, image pan and zoom, locked bounds, 90° rotation, aspect-ratio presets (Free, 1:1, 4:3, 16:9), and automatic downscaling under 1 MB.
icorp is a modern, premium, and fully platform-agnostic image cropping library built using Kotlin Multiplatform and Jetpack Compose Multiplatform. It targets Android, iOS, and Desktop (JVM) with 100% shared UI and business logic.
This is the standard and most reliable way to consume the library. Since the library is published on Maven Central, you do not need to add any custom repositories.
build.gradle.kts (e.g., composeApp/build.gradle.kts), add the dependency:
kotlin {
sourceSets {
commonMain.dependencies {
implementation("io.github.kvarun701:icorp:1.0.0")
}
}
}You can also import the library directly from GitHub via JitPack.
Add the JitPack Repository:
In your target project's root settings.gradle.kts (or build.gradle.kts), add the JitPack maven repository:
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven("https://jitpack.io") // Add this line
}
}Add the Dependency:
In your target project's shared/common module build.gradle.kts (e.g., composeApp/build.gradle.kts), add the dependency. Replace Tag with a release version (e.g., 1.0.0) or a specific commit hash:
kotlin {
sourceSets {
commonMain.dependencies {
implementation("com.github.kvarun701.icorp-library-for-composemultiplateform:icorp:Tag")
}
}
}This option compiles and installs the library into your local Maven cache, allowing any Compose Multiplatform project on your computer to import it.
./gradlew :icorp:publishToMavenLocalsettings.gradle.kts (or build.gradle.kts), make sure mavenLocal() is in the repository list:
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
mavenLocal() // Add this line
}
}build.gradle.kts (e.g., composeApp/build.gradle.kts), declare the dependency:
kotlin {
sourceSets {
commonMain.dependencies {
implementation("io.github.kvarun701:icorp:1.0.0")
}
}
}Copy the :library Module:
Copy the library folder from the icorp directory into your target project directory.
Include :icorp in settings.gradle.kts:
Open your target project's settings.gradle.kts and include the module:
include(":icorp")Add Project Dependency:
In your target project's shared module build.gradle.kts, add the project reference:
dependencies {
implementation(project(":icorp"))
}In your shared common code (commonMain), import the library and place the ImageCropper composable:
import androidx.compose.runtime.*
import androidx.compose.ui.graphics.ImageBitmap
import icorp.ImageCropper
@Composable
fun EditPhotoScreen() {
var activeImage by remember { mutableStateOf<ImageBitmap>(/* Load your source ImageBitmap */) }
ImageCropper(
image = activeImage,
onCropSuccess = { croppedBitmap ->
// 1. The croppedBitmap is returned here
// 2. It is guaranteed to be under 1 MB in size
// 3. You can set it as the new active image or upload it
activeImage = croppedBitmap
},
onCancel = {
// Handle cancel action (e.g., close editor or revert changes)
}
)
}In your Android module's launcher activity, simply set the content to your shared composable:
package myproject.android
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import myproject.EditPhotoScreen // Your shared composable
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
EditPhotoScreen()
}
}
}iosMain directory:
package icorp
import androidx.compose.ui.window.ComposeUIViewController
fun MainViewController() = ComposeUIViewController {
App() // Your shared Composable
}cd "$SRCROOT/.."
./gradlew :library:embedAndSignAppleFrameworkForXcodeUIViewControllerRepresentable:
import SwiftUI
import library // Your KMP framework name
struct ComposeView: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> UIViewController {
MainViewControllerKt.MainViewController()
}
func updateUIViewController(_ uiViewController: UIViewController, context: Context) {}
}
struct ContentView: View {
var body: some View {
ComposeView()
.ignoresSafeArea(.all)
}
}In your desktop app entry point:
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.application
import androidx.compose.ui.window.rememberWindowState
import myproject.EditPhotoScreen
fun main() = application {
val windowState = rememberWindowState(width = 800.dp, height = 750.dp)
Window(
onCloseRequest = ::exitApplication,
title = "Image Editor",
state = windowState
) {
EditPhotoScreen()
}
}| Parameter | Type | Description |
|---|---|---|
image |
ImageBitmap |
The source image to be edited and cropped. |
modifier |
Modifier |
Layout modifier for the overall screen container. |
onCropSuccess |
(ImageBitmap) -> Unit |
Callback triggered when the checkmark (tick) button is clicked. Returns the cropped ImageBitmap (auto-scaled under 1 MB). |
onCancel |
() -> Unit |
Callback triggered when the Close ("X") button is clicked. |
icorp is a modern, premium, and fully platform-agnostic image cropping library built using Kotlin Multiplatform and Jetpack Compose Multiplatform. It targets Android, iOS, and Desktop (JVM) with 100% shared UI and business logic.
This is the standard and most reliable way to consume the library. Since the library is published on Maven Central, you do not need to add any custom repositories.
build.gradle.kts (e.g., composeApp/build.gradle.kts), add the dependency:
kotlin {
sourceSets {
commonMain.dependencies {
implementation("io.github.kvarun701:icorp:1.0.0")
}
}
}You can also import the library directly from GitHub via JitPack.
Add the JitPack Repository:
In your target project's root settings.gradle.kts (or build.gradle.kts), add the JitPack maven repository:
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven("https://jitpack.io") // Add this line
}
}Add the Dependency:
In your target project's shared/common module build.gradle.kts (e.g., composeApp/build.gradle.kts), add the dependency. Replace Tag with a release version (e.g., 1.0.0) or a specific commit hash:
kotlin {
sourceSets {
commonMain.dependencies {
implementation("com.github.kvarun701.icorp-library-for-composemultiplateform:icorp:Tag")
}
}
}This option compiles and installs the library into your local Maven cache, allowing any Compose Multiplatform project on your computer to import it.
./gradlew :icorp:publishToMavenLocalsettings.gradle.kts (or build.gradle.kts), make sure mavenLocal() is in the repository list:
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
mavenLocal() // Add this line
}
}build.gradle.kts (e.g., composeApp/build.gradle.kts), declare the dependency:
kotlin {
sourceSets {
commonMain.dependencies {
implementation("io.github.kvarun701:icorp:1.0.0")
}
}
}Copy the :library Module:
Copy the library folder from the icorp directory into your target project directory.
Include :icorp in settings.gradle.kts:
Open your target project's settings.gradle.kts and include the module:
include(":icorp")Add Project Dependency:
In your target project's shared module build.gradle.kts, add the project reference:
dependencies {
implementation(project(":icorp"))
}In your shared common code (commonMain), import the library and place the ImageCropper composable:
import androidx.compose.runtime.*
import androidx.compose.ui.graphics.ImageBitmap
import icorp.ImageCropper
@Composable
fun EditPhotoScreen() {
var activeImage by remember { mutableStateOf<ImageBitmap>(/* Load your source ImageBitmap */) }
ImageCropper(
image = activeImage,
onCropSuccess = { croppedBitmap ->
// 1. The croppedBitmap is returned here
// 2. It is guaranteed to be under 1 MB in size
// 3. You can set it as the new active image or upload it
activeImage = croppedBitmap
},
onCancel = {
// Handle cancel action (e.g., close editor or revert changes)
}
)
}In your Android module's launcher activity, simply set the content to your shared composable:
package myproject.android
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import myproject.EditPhotoScreen // Your shared composable
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
EditPhotoScreen()
}
}
}iosMain directory:
package icorp
import androidx.compose.ui.window.ComposeUIViewController
fun MainViewController() = ComposeUIViewController {
App() // Your shared Composable
}cd "$SRCROOT/.."
./gradlew :library:embedAndSignAppleFrameworkForXcodeUIViewControllerRepresentable:
import SwiftUI
import library // Your KMP framework name
struct ComposeView: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> UIViewController {
MainViewControllerKt.MainViewController()
}
func updateUIViewController(_ uiViewController: UIViewController, context: Context) {}
}
struct ContentView: View {
var body: some View {
ComposeView()
.ignoresSafeArea(.all)
}
}In your desktop app entry point:
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.application
import androidx.compose.ui.window.rememberWindowState
import myproject.EditPhotoScreen
fun main() = application {
val windowState = rememberWindowState(width = 800.dp, height = 750.dp)
Window(
onCloseRequest = ::exitApplication,
title = "Image Editor",
state = windowState
) {
EditPhotoScreen()
}
}| Parameter | Type | Description |
|---|---|---|
image |
ImageBitmap |
The source image to be edited and cropped. |
modifier |
Modifier |
Layout modifier for the overall screen container. |
onCropSuccess |
(ImageBitmap) -> Unit |
Callback triggered when the checkmark (tick) button is clicked. Returns the cropped ImageBitmap (auto-scaled under 1 MB). |
onCancel |
() -> Unit |
Callback triggered when the Close ("X") button is clicked. |