Skip to content

Commit

Permalink
Ensuring compression quality value is in range 0.0 .. 1.0
Browse files Browse the repository at this point in the history
Adding annotation library and marking compressionQuality param as FloatRange.
  • Loading branch information
shtolik committed Mar 7, 2024
1 parent 0b73d49 commit bbb5fa8
Show file tree
Hide file tree
Showing 5 changed files with 16 additions and 3 deletions.
1 change: 1 addition & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ androidx-exifinterface = { group = "androidx.exifinterface", name = "exifinterfa
androidx-lifecycle-viewmodel-compose = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-compose", version.ref = "androidx-lifecycleViewmodelCompose" }
paging-common = { module = "app.cash.paging:paging-common", version.ref = "multiplatform-paging" }
paging-compose-common = { module = "app.cash.paging:paging-compose-common", version.ref = "multiplatform-paging" }
annotation = { module = "androidx.annotation:annotation", version = "1.7.1" }

[plugins]
androidApplication = { id = "com.android.application", version.ref = "agp" }
Expand Down
1 change: 1 addition & 0 deletions peekaboo-image-picker/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ kotlin {
implementation(compose.runtime)
implementation(compose.foundation)
implementation(compose.material)
implementation(libs.annotation)
}
commonTest.dependencies {
implementation(libs.kotlin.test)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import android.graphics.Matrix
import android.graphics.Paint
import android.net.Uri
import android.provider.OpenableColumns
import androidx.annotation.FloatRange
import androidx.exifinterface.media.ExifInterface
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
Expand All @@ -40,6 +41,7 @@ internal object PeekabooImageResizer {
width: Int,
height: Int,
resizeThresholdBytes: Long,
@FloatRange(from = 0.0, to = 1.0)
compressionQuality: Double,
filterOptions: FilterOptions,
onResult: (ByteArray?) -> Unit,
Expand Down Expand Up @@ -87,6 +89,7 @@ internal object PeekabooImageResizer {
uri: Uri,
width: Int,
height: Int,
@FloatRange(from = 0.0, to = 1.0)
compression: Double,
filterOptions: FilterOptions,
): ByteArray? {
Expand Down Expand Up @@ -129,7 +132,8 @@ internal object PeekabooImageResizer {
val filteredBitmap = applyFilter(rotatedBitmap, filterOptions)

ByteArrayOutputStream().use { byteArrayOutputStream ->
filteredBitmap.compress(Bitmap.CompressFormat.JPEG, (100 * compression).toInt(), byteArrayOutputStream)
val validatedCompression = compression.coerceIn(0.0, 1.0)
filteredBitmap.compress(Bitmap.CompressFormat.JPEG, (100 * validatedCompression).toInt(), byteArrayOutputStream)
val byteArray = byteArrayOutputStream.toByteArray()
PeekabooBitmapCache.instance.put(filterCacheKey, filteredBitmap)
return byteArray
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package com.preat.peekaboo.image.picker

import androidx.annotation.FloatRange
import androidx.compose.runtime.Composable
import kotlinx.coroutines.CoroutineScope

Expand Down Expand Up @@ -45,6 +46,7 @@ data class ResizeOptions(
val width: Int = DEFAULT_RESIZE_IMAGE_WIDTH,
val height: Int = DEFAULT_RESIZE_IMAGE_HEIGHT,
val resizeThresholdBytes: Long = DEFAULT_RESIZE_THRESHOLD_BYTES,
@FloatRange(from = 0.0, to = 1.0)
val compressionQuality: Double = 1.0,
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package com.preat.peekaboo.image.picker

import androidx.annotation.FloatRange
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import kotlinx.cinterop.CValue
Expand Down Expand Up @@ -86,6 +87,7 @@ actual fun rememberImagePickerLauncher(
resizeOptions.width,
resizeOptions.height,
resizeOptions.resizeThresholdBytes,
resizeOptions.compressionQuality,
filterOptions,
)
val bytes = resizedImage?.toByteArray(resizeOptions.compressionQuality)
Expand Down Expand Up @@ -123,7 +125,8 @@ actual fun rememberImagePickerLauncher(

@OptIn(ExperimentalForeignApi::class)
private fun UIImage.toByteArray(compressionQuality: Double): ByteArray {
val jpegData = UIImageJPEGRepresentation(this, compressionQuality)!!
val validCompressionQuality = compressionQuality.coerceIn(0.0, 1.0)
val jpegData = UIImageJPEGRepresentation(this, validCompressionQuality)!!
return ByteArray(jpegData.length.toInt()).apply {
memcpy(this.refTo(0), jpegData.bytes, jpegData.length)
}
Expand All @@ -134,9 +137,11 @@ private fun UIImage.fitInto(
maxWidth: Int,
maxHeight: Int,
resizeThresholdBytes: Long,
@FloatRange(from = 0.0, to = 1.0)
compressionQuality: Double,
filterOptions: FilterOptions,
): UIImage {
val imageData = this.toByteArray()
val imageData = this.toByteArray(compressionQuality)
if (imageData.size > resizeThresholdBytes) {
val originalWidth = this.size.useContents { width }
val originalHeight = this.size.useContents { height }
Expand Down

0 comments on commit bbb5fa8

Please sign in to comment.