Skip to content

Commit

Permalink
Improve image splitter and add Quality controlling for watermarking o…
Browse files Browse the repository at this point in the history
…ption by #1192
  • Loading branch information
T8RIN committed Jul 7, 2024
1 parent e677278 commit b1330a8
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,8 @@

package ru.tech.imageresizershrinker.image_splitting.data

import android.content.Context
import android.graphics.Bitmap
import androidx.exifinterface.media.ExifInterface
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.async
import kotlinx.coroutines.withContext
Expand All @@ -35,7 +33,6 @@ import ru.tech.imageresizershrinker.image_splitting.domain.SplitParams
import javax.inject.Inject

internal class AndroidImageSplitter @Inject constructor(
@ApplicationContext private val context: Context,
private val imageGetter: ImageGetter<Bitmap, ExifInterface>,
private val shareProvider: ShareProvider<Bitmap>,
dispatchersHolder: DispatchersHolder
Expand All @@ -56,16 +53,16 @@ internal class AndroidImageSplitter @Inject constructor(
) ?: return@withContext emptyList()

if (params.rowsCount <= 1) {
splitForRows(
splitForColumns(
image = image,
count = params.rowsCount,
count = params.columnsCount,
imageFormat = params.imageFormat,
quality = params.quality
)
} else if (params.columnsCount <= 1) {
splitForColumns(
splitForRows(
image = image,
count = params.columnsCount,
count = params.rowsCount,
imageFormat = params.imageFormat,
quality = params.quality
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package ru.tech.imageresizershrinker.image_splitting.presentation

import android.net.Uri
import androidx.activity.ComponentActivity
import androidx.compose.animation.animateContentSize
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.aspectRatio
Expand Down Expand Up @@ -163,6 +164,9 @@ fun ImageSplitterContent(
uris = viewModel.uris.ifEmpty {
listOf(Uri.EMPTY, Uri.EMPTY)
},
modifier = Modifier
.animateContentSize()
.padding(2.dp),
isPortrait = true,
onRemoveUri = null,
onAddUris = null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,17 @@

package ru.tech.imageresizershrinker.image_splitting.presentation.components

import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.TableRows
import androidx.compose.material.icons.rounded.ViewColumn
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
Expand All @@ -37,12 +40,15 @@ import ru.tech.imageresizershrinker.image_splitting.domain.SplitParams
import kotlin.math.roundToInt

@Composable
internal fun ColumnScope.SplitParamsSelector(
internal fun SplitParamsSelector(
value: SplitParams,
onValueChange: (SplitParams) -> Unit
) {
var rowsCount by remember {
mutableIntStateOf(value.rowsCount)
}
EnhancedSliderItem(
value = value.rowsCount,
value = rowsCount,
title = stringResource(R.string.rows_count),
sliderModifier = Modifier
.padding(
Expand All @@ -52,22 +58,26 @@ internal fun ColumnScope.SplitParamsSelector(
bottom = 10.dp
),
icon = Icons.Rounded.TableRows,
valueRange = 2f..20f,
steps = 17,
valueRange = 1f..20f,
steps = 18,
internalStateTransformation = {
it.roundToInt()
},
onValueChangeFinished = {
onValueChange(
value.copy(rowsCount = it.roundToInt())
)
rowsCount = it.roundToInt()
},
onValueChange = {},
shape = ContainerShapeDefaults.topShape
)
Spacer(Modifier.height(3.dp))
Spacer(Modifier.height(4.dp))
var columnsCount by remember {
mutableIntStateOf(value.columnsCount)
}
EnhancedSliderItem(
value = value.columnsCount,
value = columnsCount,
title = stringResource(R.string.columns_count),
sliderModifier = Modifier
.padding(
Expand All @@ -76,16 +86,17 @@ internal fun ColumnScope.SplitParamsSelector(
end = 12.dp,
bottom = 10.dp
),
steps = 17,
steps = 18,
icon = Icons.Rounded.ViewColumn,
valueRange = 2f..20f,
valueRange = 1f..20f,
internalStateTransformation = {
it.roundToInt()
},
onValueChangeFinished = {
onValueChange(
value.copy(columnsCount = it.roundToInt())
)
columnsCount = it.roundToInt()
},
onValueChange = {},
shape = ContainerShapeDefaults.bottomShape
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Job
import ru.tech.imageresizershrinker.core.domain.dispatchers.DispatchersHolder
import ru.tech.imageresizershrinker.core.domain.image.ImageCompressor
import ru.tech.imageresizershrinker.core.domain.image.ShareProvider
import ru.tech.imageresizershrinker.core.domain.image.model.ImageInfo
import ru.tech.imageresizershrinker.core.domain.saving.FileController
Expand All @@ -46,7 +45,6 @@ import javax.inject.Inject
@HiltViewModel
class ImageSplitterViewModel @Inject constructor(
private val fileController: FileController,
private val imageCompressor: ImageCompressor<Bitmap>,
private val imageSplitter: ImageSplitter<Bitmap>,
private val shareProvider: ShareProvider<Bitmap>,
dispatchersHolder: DispatchersHolder
Expand Down Expand Up @@ -89,9 +87,11 @@ class ImageSplitterViewModel @Inject constructor(
}

fun updateParams(params: SplitParams) {
_params.update { params }
registerChanges()
updateUris()
if (params != this.params) {
_params.update { params }
registerChanges()
updateUris()
}
}

private var savingJob: Job? by smartJob {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.PhotoSizeSelectSmall
import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.derivedStateOf
Expand Down Expand Up @@ -100,14 +101,18 @@ fun ImageScaleSelector(
Row(
modifier = Modifier
.padding(4.dp)
.container(RoundedCornerShape(20.dp))
.container(
RoundedCornerShape(20.dp),
color = MaterialTheme.colorScheme.surface
)
.padding(4.dp)
) {
Column(
modifier = Modifier
.weight(1f)
.container(
autoShadowElevation = 0.2.dp
autoShadowElevation = 0.2.dp,
color = MaterialTheme.colorScheme.surfaceContainerLow
)
.padding(4.dp),
verticalArrangement = Arrangement.Center,
Expand All @@ -127,7 +132,8 @@ fun ImageScaleSelector(
modifier = Modifier
.weight(1f)
.container(
autoShadowElevation = 0.2.dp
autoShadowElevation = 0.2.dp,
color = MaterialTheme.colorScheme.surfaceContainerLow
)
.padding(4.dp),
verticalArrangement = Arrangement.Center,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ import ru.tech.imageresizershrinker.core.ui.widget.buttons.ShowOriginalButton
import ru.tech.imageresizershrinker.core.ui.widget.buttons.ZoomButton
import ru.tech.imageresizershrinker.core.ui.widget.controls.SaveExifWidget
import ru.tech.imageresizershrinker.core.ui.widget.controls.selection.ImageFormatSelector
import ru.tech.imageresizershrinker.core.ui.widget.controls.selection.QualitySelector
import ru.tech.imageresizershrinker.core.ui.widget.dialogs.ExitWithoutSavingDialog
import ru.tech.imageresizershrinker.core.ui.widget.dialogs.OneTimeSaveLocationSelectionDialog
import ru.tech.imageresizershrinker.core.ui.widget.dialogs.ResetDialog
Expand Down Expand Up @@ -284,6 +285,14 @@ fun WatermarkingContent(
imageFormat = viewModel.imageFormat,
onCheckedChange = viewModel::toggleKeepExif
)
if (viewModel.imageFormat.canChangeCompressionValue) {
Spacer(Modifier.height(8.dp))
}
QualitySelector(
imageFormat = viewModel.imageFormat,
quality = viewModel.quality,
onQualityChange = viewModel::setQuality
)
Spacer(modifier = Modifier.height(8.dp))
ImageFormatSelector(
value = viewModel.imageFormat,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import ru.tech.imageresizershrinker.core.domain.image.ImageScaler
import ru.tech.imageresizershrinker.core.domain.image.ShareProvider
import ru.tech.imageresizershrinker.core.domain.image.model.ImageFormat
import ru.tech.imageresizershrinker.core.domain.image.model.ImageInfo
import ru.tech.imageresizershrinker.core.domain.image.model.Quality
import ru.tech.imageresizershrinker.core.domain.image.model.ResizeType
import ru.tech.imageresizershrinker.core.domain.saving.FileController
import ru.tech.imageresizershrinker.core.domain.saving.model.ImageSaveTarget
Expand Down Expand Up @@ -86,9 +87,12 @@ class WatermarkingViewModel @Inject constructor(
private val _watermarkParams = mutableStateOf(WatermarkParams.Default)
val watermarkParams by _watermarkParams

private val _imageFormat = mutableStateOf(ImageFormat.Default)
private val _imageFormat: MutableState<ImageFormat> = mutableStateOf(ImageFormat.Default)
val imageFormat by _imageFormat

private val _quality: MutableState<Quality> = mutableStateOf(Quality.Base())
val quality by _quality

private val _done: MutableState<Int> = mutableIntStateOf(0)
val done by _done

Expand Down Expand Up @@ -139,7 +143,8 @@ class WatermarkingViewModel @Inject constructor(
val imageInfo = ImageInfo(
imageFormat = imageFormat,
width = localBitmap.width,
height = localBitmap.height
height = localBitmap.height,
quality = quality
)

results.add(
Expand Down Expand Up @@ -198,7 +203,8 @@ class WatermarkingViewModel @Inject constructor(
it to ImageInfo(
width = it.width,
height = it.height,
imageFormat = imageFormat
imageFormat = imageFormat,
quality = quality
)
}
},
Expand All @@ -224,6 +230,11 @@ class WatermarkingViewModel @Inject constructor(
_left.value = -1
}

fun setQuality(quality: Quality) {
_quality.update { quality }
registerChanges()
}

fun setImageFormat(imageFormat: ImageFormat) {
_imageFormat.update { imageFormat }
registerChanges()
Expand Down Expand Up @@ -292,9 +303,9 @@ class WatermarkingViewModel @Inject constructor(
fun getWatermarkTransformation(): Transformation {
return GenericTransformation<Bitmap>(watermarkParams) { input, size ->
imageScaler.scaleImage(
getWatermarkedBitmap(input) ?: input,
size.width,
size.height,
image = getWatermarkedBitmap(input) ?: input,
width = size.width,
height = size.height,
resizeType = ResizeType.Flexible
)
}.toCoil()
Expand All @@ -312,7 +323,8 @@ class WatermarkingViewModel @Inject constructor(
it to ImageInfo(
width = it.width,
height = it.height,
imageFormat = imageFormat
imageFormat = imageFormat,
quality = quality
)
}?.let { (image, imageInfo) ->
shareProvider.cacheImage(
Expand Down Expand Up @@ -342,7 +354,8 @@ class WatermarkingViewModel @Inject constructor(
it to ImageInfo(
width = it.width,
height = it.height,
imageFormat = imageFormat
imageFormat = imageFormat,
quality = quality
)
}?.let { (image, imageInfo) ->
shareProvider.cacheImage(
Expand Down

0 comments on commit b1330a8

Please sign in to comment.