Skip to content

Commit a6d83a6

Browse files
try image cropper in sample app
1 parent e84e971 commit a6d83a6

3 files changed

Lines changed: 71 additions & 9 deletions

File tree

app/src/main/java/com/streamliners/feature/pickers_sample/comp/MediaPickerSample.kt

Lines changed: 64 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
package com.streamliners.feature.pickers_sample.comp
22

3+
import android.content.Context
4+
import android.graphics.Bitmap
5+
import android.net.Uri
36
import androidx.compose.foundation.layout.Arrangement
47
import androidx.compose.foundation.layout.Column
5-
import androidx.compose.foundation.layout.Spacer
68
import androidx.compose.foundation.layout.fillMaxWidth
79
import androidx.compose.foundation.layout.padding
8-
import androidx.compose.foundation.layout.size
910
import androidx.compose.material3.Button
10-
import androidx.compose.material3.Card
1111
import androidx.compose.material3.ElevatedCard
1212
import androidx.compose.material3.HorizontalDivider
1313
import androidx.compose.material3.MaterialTheme
@@ -18,7 +18,18 @@ import androidx.compose.runtime.mutableStateOf
1818
import androidx.compose.runtime.remember
1919
import androidx.compose.ui.Alignment.Companion.CenterHorizontally
2020
import androidx.compose.ui.Modifier
21+
import androidx.compose.ui.graphics.ImageBitmap
22+
import androidx.compose.ui.graphics.asAndroidBitmap
23+
import androidx.compose.ui.platform.LocalContext
2124
import androidx.compose.ui.unit.dp
25+
import androidx.core.net.toUri
26+
import com.mr0xf00.easycrop.AspectRatio
27+
import com.mr0xf00.easycrop.CropError
28+
import com.mr0xf00.easycrop.CropResult
29+
import com.mr0xf00.easycrop.CropperStyle
30+
import com.mr0xf00.easycrop.crop
31+
import com.mr0xf00.easycrop.rememberImageCropper
32+
import com.mr0xf00.easycrop.ui.ImageCropperDialog
2233
import com.streamliners.compose.comp.select.LabelledCheckBox
2334
import com.streamliners.compose.comp.select.RadioGroup
2435
import com.streamliners.pickers.media.FromGalleryType
@@ -28,6 +39,9 @@ import com.streamliners.pickers.media.MediaType
2839
import com.streamliners.pickers.media.PickedMedia
2940
import com.streamliners.pickers.media.comp.PickedMediaPreviewList
3041
import com.streamliners.pickers.media.rememberMediaPickerDialogState
42+
import com.streamliners.pickers.media.util.createFile
43+
import com.streamliners.pickers.media.util.getUri
44+
import java.io.FileOutputStream
3145

3246
@Composable
3347
fun MediaPickerSample(
@@ -36,6 +50,8 @@ fun MediaPickerSample(
3650

3751
val mediaPickerDialogState = rememberMediaPickerDialogState()
3852

53+
val imageCropper = rememberImageCropper()
54+
3955
ElevatedCard(
4056
modifier = Modifier.fillMaxWidth()
4157
) {
@@ -80,6 +96,8 @@ fun MediaPickerSample(
8096
mutableStateListOf<PickedMedia>()
8197
}
8298

99+
val context = LocalContext.current
100+
83101
Button(
84102
modifier = Modifier.align(CenterHorizontally),
85103
enabled = type.value != null && fromGalleryType.value != null,
@@ -91,6 +109,25 @@ fun MediaPickerSample(
91109
callback = { getResult ->
92110
executeHandlingError {
93111
pickedMediaList.addAll(getResult())
112+
113+
val firstMedia = pickedMediaList.firstOrNull() ?: error("no media picked")
114+
if (firstMedia is PickedMedia.Image) {
115+
116+
val result = imageCropper.crop(firstMedia.uri.toUri(), context)
117+
when (result) {
118+
CropResult.Cancelled -> {
119+
120+
}
121+
is CropError -> {
122+
error("Crop error")
123+
}
124+
is CropResult.Success -> {
125+
val croppedImageUri = saveBitmapToFile(context, result.bitmap)
126+
pickedMediaList.remove(firstMedia)
127+
pickedMediaList.add(firstMedia.copy(uri = croppedImageUri.toString()))
128+
}
129+
}
130+
}
94131
}
95132
}
96133
)
@@ -112,4 +149,27 @@ fun MediaPickerSample(
112149
state = mediaPickerDialogState,
113150
authority = "com.streamliners.fileprovider"
114151
)
115-
}
152+
153+
imageCropper.cropState?.let {
154+
155+
ImageCropperDialog(
156+
state = it,
157+
style = CropperStyle(
158+
autoZoom = false,
159+
guidelines = null
160+
),
161+
showAspectRatioSelectionButton = false,
162+
showShapeCropButton = false,
163+
lockAspectRatio = AspectRatio(1, 1)
164+
)
165+
}
166+
}
167+
168+
fun saveBitmapToFile(context: Context, bitmap: ImageBitmap): Uri {
169+
val file = createFile(context, "${System.currentTimeMillis()}.png", "capture")
170+
val fileOutputStream = FileOutputStream(file)
171+
bitmap.asAndroidBitmap().compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream)
172+
fileOutputStream.flush()
173+
return file.getUri(context, "com.streamliners.fileprovider")
174+
}
175+

pickers/build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ dependencies {
5454
implementation("com.aminography:primedatepicker:3.6.1")
5555
implementation("com.aminography:primecalendar:1.7.0")
5656

57+
api("com.github.LavishSwarnkar:easycrop:0.1.3")
58+
5759
implementation("androidx.core:core-ktx:1.12.0")
5860
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2")
5961
implementation("androidx.activity:activity-compose:1.8.2")

pickers/src/main/java/com/streamliners/pickers/media/MediaPickerState.kt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,12 @@ sealed class MediaPickerDialogState {
2323
}
2424

2525
sealed class PickedMedia(
26-
val uri: String,
27-
val filePath: String? = null
26+
open val uri: String,
27+
open val filePath: String? = null
2828
) {
29-
class Image(
30-
uri: String,
31-
filePath: String? = null
29+
data class Image(
30+
override val uri: String,
31+
override val filePath: String? = null
3232
): PickedMedia(uri, filePath)
3333

3434
class Video(

0 commit comments

Comments
 (0)