Make metadata realization independent

This commit is contained in:
T8RIN
2025-03-31 05:37:51 +03:00
parent 1c1a978d38
commit 7a659bf520
56 changed files with 117 additions and 183 deletions

View File

@ -18,7 +18,6 @@
package ru.tech.imageresizershrinker.core.data.di
import android.graphics.Bitmap
import androidx.exifinterface.media.ExifInterface
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn

View File

@ -22,7 +22,6 @@ package ru.tech.imageresizershrinker.core.data.image
import android.content.Context
import android.graphics.Bitmap
import androidx.core.net.toUri
import androidx.exifinterface.media.ExifInterface
import com.t8rin.trickle.Trickle
import dagger.Lazy
import dagger.hilt.android.qualifiers.ApplicationContext

View File

@ -22,7 +22,6 @@ import android.content.Context
import android.graphics.Bitmap
import android.webkit.MimeTypeMap
import androidx.core.net.toUri
import androidx.exifinterface.media.ExifInterface
import coil3.ImageLoader
import coil3.gif.repeatCount
import coil3.request.ImageRequest
@ -85,21 +84,19 @@ internal class AndroidImageGetter @Inject constructor(
onFailure = onFailure
)?.let { bitmap ->
val newUri = uri.toUri().tryRequireOriginal(context)
val fd = context.contentResolver.openFileDescriptor(newUri, "r")
val exif = fd?.fileDescriptor?.let { ExifInterface(it) }
fd?.close()
ImageData(
image = bitmap,
imageInfo = ImageInfo(
width = bitmap.width,
height = bitmap.height,
imageFormat = ImageFormat[getExtension(uri)],
originalUri = uri,
resizeType = settingsState.defaultResizeType
),
metadata = exif?.toMetadata()
)
context.contentResolver.openFileDescriptor(newUri, "r").use {
ImageData(
image = bitmap,
imageInfo = ImageInfo(
width = bitmap.width,
height = bitmap.height,
imageFormat = ImageFormat[getExtension(uri)],
originalUri = uri,
resizeType = settingsState.defaultResizeType
),
metadata = it?.fileDescriptor?.toMetadata()
)
}
}
}
@ -145,20 +142,19 @@ internal class AndroidImageGetter @Inject constructor(
addSizeToRequest = originalSize
)?.let { bitmap ->
val newUri = uri.toUri().tryRequireOriginal(context)
val fd = context.contentResolver.openFileDescriptor(newUri, "r")
val exif = fd?.fileDescriptor?.let { ExifInterface(it) }
fd?.close()
ImageData(
image = bitmap,
imageInfo = ImageInfo(
width = bitmap.width,
height = bitmap.height,
imageFormat = ImageFormat[getExtension(uri)],
originalUri = uri,
resizeType = settingsState.defaultResizeType
),
metadata = exif?.toMetadata()
)
context.contentResolver.openFileDescriptor(newUri, "r").use {
ImageData(
image = bitmap,
imageInfo = ImageInfo(
width = bitmap.width,
height = bitmap.height,
imageFormat = ImageFormat[getExtension(uri)],
originalUri = uri,
resizeType = settingsState.defaultResizeType
),
metadata = it?.fileDescriptor?.toMetadata()
)
}
}
}

View File

@ -19,7 +19,6 @@ package ru.tech.imageresizershrinker.core.data.image
import android.graphics.Bitmap
import android.os.Build
import androidx.exifinterface.media.ExifInterface
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach

View File

@ -19,27 +19,30 @@ package ru.tech.imageresizershrinker.core.data.image
import androidx.exifinterface.media.ExifInterface
import ru.tech.imageresizershrinker.core.domain.image.Metadata
import ru.tech.imageresizershrinker.core.domain.image.model.MetadataTag
import java.io.FileDescriptor
private data class AndroidMetadata(
private data class ExifInterfaceMetadata(
private val exifInterface: ExifInterface
) : Metadata {
override fun saveAttributes() = exifInterface.saveAttributes()
override fun getAttribute(tag: String): String? = exifInterface.getAttribute(tag)
override fun getAttribute(tag: MetadataTag): String? = exifInterface.getAttribute(tag.key)
override fun setAttribute(
tag: String,
tag: MetadataTag,
value: String?
) = exifInterface.setAttribute(tag, value)
) = exifInterface.setAttribute(tag.key, value)
override fun removeAttribute(
tag: String
override fun clearAttribute(
tag: MetadataTag
) = setAttribute(
tag = tag,
value = null
)
}
internal fun ExifInterface.toMetadata(): Metadata = AndroidMetadata(this)
internal fun ExifInterface.toMetadata(): Metadata = ExifInterfaceMetadata(this)
internal fun FileDescriptor.toMetadata(): Metadata = ExifInterface(this).toMetadata()

View File

@ -24,11 +24,11 @@ import android.net.Uri
import android.os.Build
import androidx.compose.ui.unit.Density
import androidx.core.content.ContextCompat
import androidx.exifinterface.media.ExifInterface
import kotlinx.coroutines.coroutineScope
import ru.tech.imageresizershrinker.core.data.image.toMetadata
import ru.tech.imageresizershrinker.core.domain.image.Metadata
import ru.tech.imageresizershrinker.core.domain.image.model.MetadataTag
import ru.tech.imageresizershrinker.core.domain.image.clearAllAttributes
import ru.tech.imageresizershrinker.core.domain.image.copyTo
import ru.tech.imageresizershrinker.core.domain.utils.readableByteCount
import ru.tech.imageresizershrinker.core.domain.utils.runSuspendCatching
import java.io.OutputStream
@ -49,41 +49,27 @@ suspend fun Context.copyMetadata(
) = runSuspendCatching {
if (initialExif != null) {
getFileDescriptorFor(fileUri)?.use {
val ex = ExifInterface(it.fileDescriptor)
initialExif.copyTo(ex.toMetadata())
ex.saveAttributes()
initialExif.copyTo(it.fileDescriptor.toMetadata())
}
} else if (keepOriginalMetadata) {
val newUri = originalUri.tryRequireOriginal(this)
val exif = contentResolver
.openFileDescriptor(newUri, "r")
?.use { ExifInterface(it.fileDescriptor) }
?.use { it.fileDescriptor.toMetadata() }
getFileDescriptorFor(fileUri)?.use {
val ex = ExifInterface(it.fileDescriptor).toMetadata()
exif?.toMetadata()?.copyTo(ex)
ex.saveAttributes()
exif?.copyTo(it.fileDescriptor.toMetadata())
}
} else {
getFileDescriptorFor(fileUri)?.use {
val ex = ExifInterface(it.fileDescriptor)
MetadataTag.entries.forEach { tag ->
ex.setAttribute(tag.key, null)
it.fileDescriptor.toMetadata().apply {
clearAllAttributes()
saveAttributes()
}
ex.saveAttributes()
}
}
}
suspend infix fun Metadata.copyTo(
newExif: Metadata
) = coroutineScope {
MetadataTag.entries.forEach { attr ->
getAttribute(attr.key).let { newExif.setAttribute(attr.key, it) }
}
newExif.saveAttributes()
}
fun Context.openWriteableStream(
uri: Uri?,
onFailure: (Throwable) -> Unit = {}

View File

@ -17,15 +17,40 @@
package ru.tech.imageresizershrinker.core.domain.image
import ru.tech.imageresizershrinker.core.domain.image.model.MetadataTag
interface Metadata {
fun saveAttributes()
fun getAttribute(tag: String): String?
fun getAttribute(tag: MetadataTag): String?
fun setAttribute(
tag: String,
tag: MetadataTag,
value: String?
)
fun removeAttribute(tag: String)
fun clearAttribute(tag: MetadataTag)
}
fun Metadata.clearAttributes(
attributes: List<MetadataTag>
): Metadata = apply {
attributes.forEach(::clearAttribute)
}
fun Metadata.clearAllAttributes() = clearAttributes(attributes = MetadataTag.entries)
fun Metadata.toMap(): Map<MetadataTag, String> = mutableMapOf<MetadataTag, String>().apply {
MetadataTag.entries.forEach { tag ->
getAttribute(tag)?.let { put(tag, it) }
}
}
fun Metadata.copyTo(metadata: Metadata): Metadata {
MetadataTag.entries.forEach { attr ->
getAttribute(attr).let { metadata.setAttribute(attr, it) }
}
metadata.saveAttributes()
return metadata
}

View File

@ -31,9 +31,8 @@ import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.platform.LocalContext
import androidx.core.graphics.BitmapCompat
import androidx.core.graphics.drawable.toBitmap
import androidx.core.graphics.scale
import androidx.core.text.isDigitsOnly
import androidx.exifinterface.media.ExifInterface
import ru.tech.imageresizershrinker.core.domain.image.Metadata
import ru.tech.imageresizershrinker.core.domain.image.model.ImageInfo
import ru.tech.imageresizershrinker.core.domain.image.model.MetadataTag
import ru.tech.imageresizershrinker.core.resources.R
@ -45,14 +44,6 @@ object ImageUtils {
fun Drawable.toBitmap(): Bitmap = toBitmap(config = getSuitableConfig())
fun Metadata.toMap(): Map<MetadataTag, String> {
val hashMap = HashMap<MetadataTag, String>()
MetadataTag.entries.forEach { tag ->
getAttribute(tag.key)?.let { hashMap[tag] = it }
}
return hashMap
}
fun MetadataTag.localizedName(
context: Context,
locale: Locale? = null
@ -283,9 +274,7 @@ object ImageUtils {
true
)
} else {
Bitmap.createScaledBitmap(
this, width, height, true
)
this.scale(width, height)
}
}

View File

@ -58,13 +58,12 @@ import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.exifinterface.media.ExifInterface
import ru.tech.imageresizershrinker.core.domain.image.Metadata
import ru.tech.imageresizershrinker.core.domain.image.model.MetadataTag
import ru.tech.imageresizershrinker.core.domain.image.toMap
import ru.tech.imageresizershrinker.core.resources.R
import ru.tech.imageresizershrinker.core.resources.icons.Exif
import ru.tech.imageresizershrinker.core.ui.utils.helper.ImageUtils.localizedName
import ru.tech.imageresizershrinker.core.ui.utils.helper.ImageUtils.toMap
import ru.tech.imageresizershrinker.core.ui.widget.enhanced.EnhancedAlertDialog
import ru.tech.imageresizershrinker.core.ui.widget.enhanced.EnhancedBottomSheetDefaults
import ru.tech.imageresizershrinker.core.ui.widget.enhanced.EnhancedButton

View File

@ -26,7 +26,6 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.core.net.toUri
import androidx.exifinterface.media.ExifInterface
import com.arkivanov.decompose.ComponentContext
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory

View File

@ -24,7 +24,6 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.core.net.toUri
import androidx.exifinterface.media.ExifInterface
import com.arkivanov.decompose.ComponentContext
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory

View File

@ -23,7 +23,6 @@ import androidx.compose.runtime.MutableState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.core.net.toUri
import androidx.exifinterface.media.ExifInterface
import com.arkivanov.decompose.ComponentContext
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory

View File

@ -25,7 +25,6 @@ import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.graphics.Color
import androidx.core.net.toUri
import androidx.exifinterface.media.ExifInterface
import com.arkivanov.decompose.ComponentContext
import com.t8rin.collages.CollageType
import dagger.assisted.Assisted

View File

@ -25,7 +25,6 @@ import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.graphics.toArgb
import androidx.core.net.toUri
import androidx.exifinterface.media.ExifInterface
import coil3.transform.Transformation
import com.arkivanov.decompose.ComponentContext
import com.t8rin.opencv_tools.image_comparison.ImageDiffTool

View File

@ -23,7 +23,6 @@ import androidx.compose.runtime.MutableState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.core.net.toUri
import androidx.exifinterface.media.ExifInterface
import com.arkivanov.decompose.ComponentContext
import com.smarttoolfactory.cropper.model.AspectRatio
import com.smarttoolfactory.cropper.model.OutlineType

View File

@ -34,6 +34,7 @@ import ru.tech.imageresizershrinker.core.domain.dispatchers.DispatchersHolder
import ru.tech.imageresizershrinker.core.domain.image.ImageGetter
import ru.tech.imageresizershrinker.core.domain.image.ImageScaler
import ru.tech.imageresizershrinker.core.domain.image.ShareProvider
import ru.tech.imageresizershrinker.core.domain.image.clearAttributes
import ru.tech.imageresizershrinker.core.domain.image.model.MetadataTag
import ru.tech.imageresizershrinker.core.domain.saving.FileController
import ru.tech.imageresizershrinker.core.domain.saving.FilenameCreator
@ -156,11 +157,7 @@ class DeleteExifComponent @AssistedInject internal constructor(
imageGetter.getImage(uri.toString())
}.getOrNull()?.let {
val metadata = if (selectedTags.isNotEmpty()) {
it.metadata?.apply {
selectedTags.forEach { tag ->
setAttribute(tag.key, null)
}
}
it.metadata?.clearAttributes(selectedTags)
} else null
results.add(
@ -254,11 +251,7 @@ class DeleteExifComponent @AssistedInject internal constructor(
uri.toString()
)?.let {
val metadata = if (selectedTags.isNotEmpty()) {
it.metadata?.apply {
selectedTags.forEach { tag ->
setAttribute(tag.key, null)
}
}
it.metadata?.clearAttributes(selectedTags)
} else null
shareProvider.cacheData(

View File

@ -24,7 +24,6 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.core.net.toUri
import androidx.exifinterface.media.ExifInterface
import com.arkivanov.decompose.ComponentContext
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory

View File

@ -46,7 +46,7 @@ import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.unit.LayoutDirection
import androidx.core.content.res.ResourcesCompat
import androidx.core.graphics.applyCanvas
import androidx.exifinterface.media.ExifInterface
import androidx.core.graphics.createBitmap
import dagger.hilt.android.qualifiers.ApplicationContext
import ru.tech.imageresizershrinker.core.data.utils.density
import ru.tech.imageresizershrinker.core.data.utils.safeConfig
@ -92,11 +92,7 @@ internal class AndroidImageDrawApplier @Inject constructor(
}
is DrawBehavior.Background -> {
Bitmap.createBitmap(
drawBehavior.width,
drawBehavior.height,
Bitmap.Config.ARGB_8888
).apply {
createBitmap(drawBehavior.width, drawBehavior.height).apply {
val canvas = Canvas(this)
val paint = NativePaint().apply {
color = drawBehavior.color
@ -192,10 +188,9 @@ internal class AndroidImageDrawApplier @Inject constructor(
val filter = filterProvider.filterToTransformation(
createFilter<Triple<ImageModel, Float, Int>, Filter.SpotHeal>(
Triple(
first = Bitmap.createBitmap(
first = createBitmap(
canvasSize.width,
canvasSize.height,
Bitmap.Config.ARGB_8888
canvasSize.height
).applyCanvas {
drawColor(Color.Black.toArgb())
drawPath(
@ -531,7 +526,7 @@ internal class AndroidImageDrawApplier @Inject constructor(
private fun Bitmap.overlay(overlay: Bitmap): Bitmap {
val image = this
val config = safeConfig.toSoftware()
val finalBitmap = Bitmap.createBitmap(image.width, image.height, config)
val finalBitmap = createBitmap(image.width, image.height, config)
val canvas = Canvas(finalBitmap)
canvas.drawBitmap(image, Matrix(), null)
canvas.drawBitmap(overlay.toSoftware(), 0f, 0f, null)

View File

@ -27,7 +27,6 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.toArgb
import androidx.core.net.toUri
import androidx.exifinterface.media.ExifInterface
import com.arkivanov.decompose.ComponentContext
import com.arkivanov.decompose.childContext
import dagger.assisted.Assisted

View File

@ -32,6 +32,7 @@ import ru.tech.imageresizershrinker.core.domain.dispatchers.DispatchersHolder
import ru.tech.imageresizershrinker.core.domain.image.ImageGetter
import ru.tech.imageresizershrinker.core.domain.image.Metadata
import ru.tech.imageresizershrinker.core.domain.image.ShareProvider
import ru.tech.imageresizershrinker.core.domain.image.clearAllAttributes
import ru.tech.imageresizershrinker.core.domain.image.model.ImageFormat
import ru.tech.imageresizershrinker.core.domain.image.model.MetadataTag
import ru.tech.imageresizershrinker.core.domain.saving.FileController
@ -160,13 +161,8 @@ class EditExifComponent @AssistedInject internal constructor(
}
fun clearExif() {
val tempExif = _exif.value
MetadataTag.entries.forEach {
tempExif?.setAttribute(it.key, null)
}
_exif.update {
tempExif
}
val tempExif = _exif.value?.clearAllAttributes()
_exif.update { tempExif }
registerChanges()
}
@ -177,7 +173,7 @@ class EditExifComponent @AssistedInject internal constructor(
fun removeExifTag(tag: MetadataTag) {
val exifInterface = _exif.value
exifInterface?.setAttribute(tag.key, null)
exifInterface?.clearAttribute(tag)
updateExif(exifInterface)
}
@ -186,7 +182,7 @@ class EditExifComponent @AssistedInject internal constructor(
value: String,
) {
val exifInterface = _exif.value
exifInterface?.setAttribute(tag.key, value)
exifInterface?.setAttribute(tag, value)
updateExif(exifInterface)
}

View File

@ -25,7 +25,6 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Path
import androidx.core.net.toUri
import androidx.exifinterface.media.ExifInterface
import com.arkivanov.decompose.ComponentContext
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory

View File

@ -18,7 +18,6 @@
package ru.tech.imageresizershrinker.feature.filters.data.model
import android.graphics.Bitmap
import androidx.exifinterface.media.ExifInterface
import com.t8rin.trickle.Trickle
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory

View File

@ -18,7 +18,6 @@
package ru.tech.imageresizershrinker.feature.filters.data.model
import android.graphics.Bitmap
import androidx.exifinterface.media.ExifInterface
import com.t8rin.trickle.Trickle
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory

View File

@ -18,7 +18,6 @@
package ru.tech.imageresizershrinker.feature.filters.data.model
import android.graphics.Bitmap
import androidx.exifinterface.media.ExifInterface
import com.awxkee.aire.Aire
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory

View File

@ -18,7 +18,6 @@
package ru.tech.imageresizershrinker.feature.filters.data.model
import android.graphics.Bitmap
import androidx.exifinterface.media.ExifInterface
import com.t8rin.opencv_tools.spot_heal.SpotHealer
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory

View File

@ -26,7 +26,6 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Path
import androidx.core.net.toUri
import androidx.exifinterface.media.ExifInterface
import coil3.transform.Transformation
import com.arkivanov.decompose.ComponentContext
import com.arkivanov.decompose.childContext

View File

@ -24,7 +24,6 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.core.net.toUri
import androidx.exifinterface.media.ExifInterface
import com.arkivanov.decompose.ComponentContext
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory

View File

@ -22,7 +22,6 @@ import android.net.Uri
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.exifinterface.media.ExifInterface
import com.arkivanov.decompose.ComponentContext
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory

View File

@ -25,7 +25,6 @@ import androidx.compose.runtime.MutableState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.exifinterface.media.ExifInterface
import com.arkivanov.decompose.ComponentContext
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory

View File

@ -30,7 +30,6 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ShaderBrush
import androidx.compose.ui.graphics.TileMode
import androidx.core.net.toUri
import androidx.exifinterface.media.ExifInterface
import coil3.transform.Transformation
import com.arkivanov.decompose.ComponentContext
import dagger.assisted.Assisted

View File

@ -19,7 +19,7 @@ package ru.tech.imageresizershrinker.image_cutting.data
import android.graphics.Bitmap
import androidx.core.graphics.applyCanvas
import androidx.exifinterface.media.ExifInterface
import androidx.core.graphics.createBitmap
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.withContext
import ru.tech.imageresizershrinker.core.data.utils.safeConfig
@ -53,7 +53,7 @@ internal class AndroidImageCutter @Inject constructor(
override suspend fun cutAndMerge(
image: Bitmap,
params: CutParams
): Bitmap? = withContext(defaultDispatcher) {
): Bitmap = withContext(defaultDispatcher) {
runSuspendCatching {
val verticalStart = params.vertical.takeIf { it != PivotPair(0f, 1f) }
?.let { (it.start * image.width).roundToInt() }
@ -180,7 +180,7 @@ internal class AndroidImageCutter @Inject constructor(
val mergedWidth = parts.maxOf { it.width }
val mergedHeight = parts.sumOf { it.height }
Bitmap.createBitmap(mergedWidth, mergedHeight, source.safeConfig)
createBitmap(mergedWidth, mergedHeight, source.safeConfig)
.applyCanvas {
var offsetY = 0f
for (part in parts) {
@ -257,7 +257,7 @@ internal class AndroidImageCutter @Inject constructor(
val mergedWidth = parts.sumOf { it.width }
val mergedHeight = parts.maxOf { it.height }
Bitmap.createBitmap(mergedWidth, mergedHeight, source.safeConfig)
createBitmap(mergedWidth, mergedHeight, source.safeConfig)
.applyCanvas {
var offsetX = 0f
for (part in parts) {

View File

@ -24,7 +24,6 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.core.net.toUri
import androidx.exifinterface.media.ExifInterface
import coil3.transform.Transformation
import com.arkivanov.decompose.ComponentContext
import dagger.assisted.Assisted
@ -324,11 +323,11 @@ class ImageCutterComponent @AssistedInject internal constructor(
else null
fun getCutTransformation(): List<Transformation> = listOf(
GenericTransformation<Bitmap> {
GenericTransformation { image: Bitmap ->
val bitmap = imageCutter.cutAndMerge(
image = it,
image = image,
params = params
) ?: it
) ?: image
imagePreviewCreator.createPreview(
image = bitmap,
@ -340,7 +339,7 @@ class ImageCutterComponent @AssistedInject internal constructor(
),
transformations = emptyList(),
onGetByteCount = {}
) ?: it
) ?: image
}.toCoil()
)

View File

@ -23,7 +23,6 @@ import androidx.compose.runtime.MutableState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.core.net.toUri
import androidx.exifinterface.media.ExifInterface
import com.arkivanov.decompose.ComponentContext
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory

View File

@ -18,7 +18,6 @@
package ru.tech.imageresizershrinker.image_splitting.data
import android.graphics.Bitmap
import androidx.exifinterface.media.ExifInterface
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.async
import kotlinx.coroutines.withContext

View File

@ -21,7 +21,7 @@ import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.PorterDuffXfermode
import androidx.exifinterface.media.ExifInterface
import androidx.core.graphics.createBitmap
import kotlinx.coroutines.withContext
import ru.tech.imageresizershrinker.core.data.image.utils.drawBitmap
import ru.tech.imageresizershrinker.core.data.image.utils.toPorterDuffMode
@ -67,10 +67,10 @@ internal class AndroidImageStacker @Inject constructor(
return@withContext null
}
val outputBitmap = Bitmap.createBitmap(
resultSize.width,
resultSize.height,
getSuitableConfig()
val outputBitmap = createBitmap(
width = resultSize.width,
height = resultSize.height,
config = getSuitableConfig()
)
val canvas = Canvas(outputBitmap)

View File

@ -22,7 +22,7 @@ import android.graphics.Canvas
import android.graphics.PorterDuff
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import androidx.exifinterface.media.ExifInterface
import androidx.core.graphics.createBitmap
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
@ -106,7 +106,7 @@ internal class AndroidImageCombiner @Inject constructor(
} else image
}
val bitmap = Bitmap.createBitmap(size.width, size.height, getSuitableConfig())
val bitmap = createBitmap(size.width, size.height, getSuitableConfig())
val canvas = Canvas(bitmap).apply {
drawColor(Color.Transparent.toArgb(), PorterDuff.Mode.CLEAR)
drawColor(combiningParams.backgroundColor)

View File

@ -22,7 +22,6 @@ import android.graphics.Bitmap
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import androidx.core.net.toUri
import androidx.exifinterface.media.ExifInterface
import com.awxkee.jxlcoder.JxlAnimatedEncoder
import com.awxkee.jxlcoder.JxlAnimatedImage
import com.awxkee.jxlcoder.JxlChannelsConfiguration

View File

@ -25,7 +25,6 @@ import androidx.compose.runtime.MutableState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.exifinterface.media.ExifInterface
import com.arkivanov.decompose.ComponentContext
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory

View File

@ -25,7 +25,6 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.core.net.toUri
import androidx.exifinterface.media.ExifInterface
import com.arkivanov.decompose.ComponentContext
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory

View File

@ -25,7 +25,6 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.core.net.toUri
import androidx.exifinterface.media.ExifInterface
import com.arkivanov.decompose.ComponentContext
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory

View File

@ -29,8 +29,8 @@ import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.asAndroidBitmap
import androidx.compose.ui.graphics.toArgb
import androidx.core.graphics.applyCanvas
import androidx.core.graphics.createBitmap
import androidx.core.net.toUri
import androidx.exifinterface.media.ExifInterface
import com.arkivanov.decompose.ComponentContext
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
@ -277,8 +277,7 @@ class MarkupLayersComponent @AssistedInject internal constructor(
private suspend fun Bitmap.overlay(overlay: Bitmap): Bitmap {
val image = this
val config = image.safeConfig.toSoftware()
val finalBitmap =
Bitmap.createBitmap(image.width, image.height, config)
val finalBitmap = createBitmap(image.width, image.height, config)
val canvas = Canvas(finalBitmap)
canvas.drawBitmap(image, Matrix(), null)
canvas.drawBitmap(

View File

@ -23,7 +23,6 @@ import androidx.compose.runtime.MutableState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.core.net.toUri
import androidx.exifinterface.media.ExifInterface
import com.arkivanov.decompose.ComponentContext
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory

View File

@ -23,7 +23,6 @@ import androidx.compose.runtime.MutableState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.graphics.Color
import androidx.exifinterface.media.ExifInterface
import com.arkivanov.decompose.ComponentContext
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory

View File

@ -20,7 +20,6 @@ package ru.tech.imageresizershrinker.feature.recognize.text.data
import android.content.Context
import android.graphics.Bitmap
import androidx.core.net.toUri
import androidx.exifinterface.media.ExifInterface
import com.googlecode.tesseract.android.TessBaseAPI
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.isActive

View File

@ -26,7 +26,6 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.exifinterface.media.ExifInterface
import com.arkivanov.decompose.ComponentContext
import com.smarttoolfactory.cropper.model.AspectRatio
import com.smarttoolfactory.cropper.model.OutlineType
@ -385,7 +384,7 @@ class RecognizeTextComponent @AssistedInject internal constructor(
sequenceNumber = null,
metadata = it.metadata?.apply {
setAttribute(
MetadataTag.UserComment.key,
MetadataTag.UserComment,
txtString.takeIf { it.isNotEmpty() }
)
},
@ -771,7 +770,7 @@ class RecognizeTextComponent @AssistedInject internal constructor(
val exif = it.metadata?.apply {
setAttribute(
MetadataTag.UserComment.key,
MetadataTag.UserComment,
txtString.takeIf { it.isNotEmpty() }
)
}

View File

@ -38,6 +38,7 @@ import ru.tech.imageresizershrinker.core.domain.image.ImageScaler
import ru.tech.imageresizershrinker.core.domain.image.ImageTransformer
import ru.tech.imageresizershrinker.core.domain.image.Metadata
import ru.tech.imageresizershrinker.core.domain.image.ShareProvider
import ru.tech.imageresizershrinker.core.domain.image.clearAllAttributes
import ru.tech.imageresizershrinker.core.domain.image.model.ImageData
import ru.tech.imageresizershrinker.core.domain.image.model.ImageFormat
import ru.tech.imageresizershrinker.core.domain.image.model.ImageInfo
@ -519,10 +520,7 @@ class ResizeAndConvertComponent @AssistedInject internal constructor(
fun canShow(): Boolean = bitmap?.let { imagePreviewCreator.canShow(it) } == true
fun clearExif() {
val tempExif = _exif.value
MetadataTag.entries.forEach {
tempExif?.setAttribute(it.key, null)
}
val tempExif = _exif.value?.clearAllAttributes()
_exif.update { tempExif }
}
@ -533,7 +531,7 @@ class ResizeAndConvertComponent @AssistedInject internal constructor(
fun removeExifTag(tag: MetadataTag) {
val exifInterface = _exif.value
exifInterface?.setAttribute(tag.key, null)
exifInterface?.clearAttribute(tag)
updateExif(exifInterface)
}
@ -542,7 +540,7 @@ class ResizeAndConvertComponent @AssistedInject internal constructor(
value: String
) {
val exifInterface = _exif.value
exifInterface?.setAttribute(tag.key, value)
exifInterface?.setAttribute(tag, value)
updateExif(exifInterface)
}

View File

@ -24,7 +24,6 @@ import androidx.compose.runtime.MutableState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.core.net.toUri
import androidx.exifinterface.media.ExifInterface
import com.arkivanov.decompose.ComponentContext
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory

View File

@ -24,7 +24,6 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import androidx.exifinterface.media.ExifInterface
import com.arkivanov.decompose.ComponentContext
import com.arkivanov.decompose.value.Value
import com.t8rin.dynamic.theme.ColorTuple

View File

@ -45,6 +45,7 @@ import ru.tech.imageresizershrinker.core.domain.image.ImageScaler
import ru.tech.imageresizershrinker.core.domain.image.ImageTransformer
import ru.tech.imageresizershrinker.core.domain.image.Metadata
import ru.tech.imageresizershrinker.core.domain.image.ShareProvider
import ru.tech.imageresizershrinker.core.domain.image.clearAllAttributes
import ru.tech.imageresizershrinker.core.domain.image.model.ImageData
import ru.tech.imageresizershrinker.core.domain.image.model.ImageFormat
import ru.tech.imageresizershrinker.core.domain.image.model.ImageInfo
@ -563,13 +564,8 @@ class SingleEditComponent @AssistedInject internal constructor(
}
fun clearExif() {
val tempExif = _exif.value
MetadataTag.entries.forEach {
tempExif?.setAttribute(it.key, null)
}
_exif.update {
tempExif
}
val tempExif = _exif.value?.clearAllAttributes()
_exif.update { tempExif }
registerChanges()
}
@ -580,7 +576,7 @@ class SingleEditComponent @AssistedInject internal constructor(
fun removeExifTag(tag: MetadataTag) {
val exifInterface = _exif.value
exifInterface?.setAttribute(tag.key, null)
exifInterface?.clearAttribute(tag)
updateExif(exifInterface)
}
@ -589,7 +585,7 @@ class SingleEditComponent @AssistedInject internal constructor(
value: String,
) {
val exifInterface = _exif.value
exifInterface?.setAttribute(tag.key, value)
exifInterface?.setAttribute(tag, value)
updateExif(exifInterface)
}

View File

@ -21,7 +21,6 @@ package ru.tech.imageresizershrinker.feature.svg_maker.data
import android.content.Context
import android.graphics.Bitmap
import androidx.exifinterface.media.ExifInterface
import com.t8rin.image.toolbox.svg.ImageTracerAndroid
import com.t8rin.image.toolbox.svg.ImageTracerAndroid.SvgListener
import dagger.hilt.android.qualifiers.ApplicationContext

View File

@ -25,7 +25,6 @@ import androidx.compose.runtime.MutableState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.exifinterface.media.ExifInterface
import com.arkivanov.decompose.ComponentContext
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory

View File

@ -27,7 +27,6 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import androidx.core.content.res.ResourcesCompat
import androidx.core.graphics.applyCanvas
import androidx.exifinterface.media.ExifInterface
import coil3.transform.RoundedCornersTransformation
import com.watermark.androidwm.WatermarkBuilder
import com.watermark.androidwm.bean.WatermarkImage

View File

@ -24,7 +24,6 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.core.net.toUri
import androidx.exifinterface.media.ExifInterface
import coil3.transform.Transformation
import com.arkivanov.decompose.ComponentContext
import dagger.assisted.Assisted

View File

@ -22,7 +22,6 @@ import android.graphics.Bitmap
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import androidx.core.net.toUri
import androidx.exifinterface.media.ExifInterface
import com.t8rin.awebp.decoder.AnimatedWebpDecoder
import com.t8rin.awebp.encoder.AnimatedWebpEncoder
import dagger.hilt.android.qualifiers.ApplicationContext

View File

@ -24,7 +24,6 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.core.net.toUri
import androidx.exifinterface.media.ExifInterface
import com.arkivanov.decompose.ComponentContext
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory

View File

@ -25,7 +25,6 @@ import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableLongStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.core.net.toUri
import androidx.exifinterface.media.ExifInterface
import com.arkivanov.decompose.ComponentContext
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory