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 package ru.tech.imageresizershrinker.core.data.di
import android.graphics.Bitmap import android.graphics.Bitmap
import androidx.exifinterface.media.ExifInterface
import dagger.Binds import dagger.Binds
import dagger.Module import dagger.Module
import dagger.hilt.InstallIn import dagger.hilt.InstallIn

View File

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

View File

@ -22,7 +22,6 @@ import android.content.Context
import android.graphics.Bitmap import android.graphics.Bitmap
import android.webkit.MimeTypeMap import android.webkit.MimeTypeMap
import androidx.core.net.toUri import androidx.core.net.toUri
import androidx.exifinterface.media.ExifInterface
import coil3.ImageLoader import coil3.ImageLoader
import coil3.gif.repeatCount import coil3.gif.repeatCount
import coil3.request.ImageRequest import coil3.request.ImageRequest
@ -85,10 +84,7 @@ internal class AndroidImageGetter @Inject constructor(
onFailure = onFailure onFailure = onFailure
)?.let { bitmap -> )?.let { bitmap ->
val newUri = uri.toUri().tryRequireOriginal(context) val newUri = uri.toUri().tryRequireOriginal(context)
context.contentResolver.openFileDescriptor(newUri, "r").use {
val fd = context.contentResolver.openFileDescriptor(newUri, "r")
val exif = fd?.fileDescriptor?.let { ExifInterface(it) }
fd?.close()
ImageData( ImageData(
image = bitmap, image = bitmap,
imageInfo = ImageInfo( imageInfo = ImageInfo(
@ -98,10 +94,11 @@ internal class AndroidImageGetter @Inject constructor(
originalUri = uri, originalUri = uri,
resizeType = settingsState.defaultResizeType resizeType = settingsState.defaultResizeType
), ),
metadata = exif?.toMetadata() metadata = it?.fileDescriptor?.toMetadata()
) )
} }
} }
}
override suspend fun getImage( override suspend fun getImage(
data: Any, data: Any,
@ -145,9 +142,7 @@ internal class AndroidImageGetter @Inject constructor(
addSizeToRequest = originalSize addSizeToRequest = originalSize
)?.let { bitmap -> )?.let { bitmap ->
val newUri = uri.toUri().tryRequireOriginal(context) val newUri = uri.toUri().tryRequireOriginal(context)
val fd = context.contentResolver.openFileDescriptor(newUri, "r") context.contentResolver.openFileDescriptor(newUri, "r").use {
val exif = fd?.fileDescriptor?.let { ExifInterface(it) }
fd?.close()
ImageData( ImageData(
image = bitmap, image = bitmap,
imageInfo = ImageInfo( imageInfo = ImageInfo(
@ -157,10 +152,11 @@ internal class AndroidImageGetter @Inject constructor(
originalUri = uri, originalUri = uri,
resizeType = settingsState.defaultResizeType resizeType = settingsState.defaultResizeType
), ),
metadata = exif?.toMetadata() metadata = it?.fileDescriptor?.toMetadata()
) )
} }
} }
}
override suspend fun getImageWithTransformations( override suspend fun getImageWithTransformations(
data: Any, data: Any,

View File

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

View File

@ -19,27 +19,30 @@ package ru.tech.imageresizershrinker.core.data.image
import androidx.exifinterface.media.ExifInterface import androidx.exifinterface.media.ExifInterface
import ru.tech.imageresizershrinker.core.domain.image.Metadata 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 private val exifInterface: ExifInterface
) : Metadata { ) : Metadata {
override fun saveAttributes() = exifInterface.saveAttributes() 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( override fun setAttribute(
tag: String, tag: MetadataTag,
value: String? value: String?
) = exifInterface.setAttribute(tag, value) ) = exifInterface.setAttribute(tag.key, value)
override fun removeAttribute( override fun clearAttribute(
tag: String tag: MetadataTag
) = setAttribute( ) = setAttribute(
tag = tag, tag = tag,
value = null 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 android.os.Build
import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.Density
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.exifinterface.media.ExifInterface
import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.coroutineScope
import ru.tech.imageresizershrinker.core.data.image.toMetadata import ru.tech.imageresizershrinker.core.data.image.toMetadata
import ru.tech.imageresizershrinker.core.domain.image.Metadata 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.readableByteCount
import ru.tech.imageresizershrinker.core.domain.utils.runSuspendCatching import ru.tech.imageresizershrinker.core.domain.utils.runSuspendCatching
import java.io.OutputStream import java.io.OutputStream
@ -49,39 +49,25 @@ suspend fun Context.copyMetadata(
) = runSuspendCatching { ) = runSuspendCatching {
if (initialExif != null) { if (initialExif != null) {
getFileDescriptorFor(fileUri)?.use { getFileDescriptorFor(fileUri)?.use {
val ex = ExifInterface(it.fileDescriptor) initialExif.copyTo(it.fileDescriptor.toMetadata())
initialExif.copyTo(ex.toMetadata())
ex.saveAttributes()
} }
} else if (keepOriginalMetadata) { } else if (keepOriginalMetadata) {
val newUri = originalUri.tryRequireOriginal(this) val newUri = originalUri.tryRequireOriginal(this)
val exif = contentResolver val exif = contentResolver
.openFileDescriptor(newUri, "r") .openFileDescriptor(newUri, "r")
?.use { ExifInterface(it.fileDescriptor) } ?.use { it.fileDescriptor.toMetadata() }
getFileDescriptorFor(fileUri)?.use { getFileDescriptorFor(fileUri)?.use {
val ex = ExifInterface(it.fileDescriptor).toMetadata() exif?.copyTo(it.fileDescriptor.toMetadata())
exif?.toMetadata()?.copyTo(ex)
ex.saveAttributes()
} }
} else { } else {
getFileDescriptorFor(fileUri)?.use { getFileDescriptorFor(fileUri)?.use {
val ex = ExifInterface(it.fileDescriptor) it.fileDescriptor.toMetadata().apply {
MetadataTag.entries.forEach { tag -> clearAllAttributes()
ex.setAttribute(tag.key, null) 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( fun Context.openWriteableStream(

View File

@ -17,15 +17,40 @@
package ru.tech.imageresizershrinker.core.domain.image package ru.tech.imageresizershrinker.core.domain.image
import ru.tech.imageresizershrinker.core.domain.image.model.MetadataTag
interface Metadata { interface Metadata {
fun saveAttributes() fun saveAttributes()
fun getAttribute(tag: String): String? fun getAttribute(tag: MetadataTag): String?
fun setAttribute( fun setAttribute(
tag: String, tag: MetadataTag,
value: String? 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.compose.ui.platform.LocalContext
import androidx.core.graphics.BitmapCompat import androidx.core.graphics.BitmapCompat
import androidx.core.graphics.drawable.toBitmap import androidx.core.graphics.drawable.toBitmap
import androidx.core.graphics.scale
import androidx.core.text.isDigitsOnly 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.ImageInfo
import ru.tech.imageresizershrinker.core.domain.image.model.MetadataTag import ru.tech.imageresizershrinker.core.domain.image.model.MetadataTag
import ru.tech.imageresizershrinker.core.resources.R import ru.tech.imageresizershrinker.core.resources.R
@ -45,14 +44,6 @@ object ImageUtils {
fun Drawable.toBitmap(): Bitmap = toBitmap(config = getSuitableConfig()) 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( fun MetadataTag.localizedName(
context: Context, context: Context,
locale: Locale? = null locale: Locale? = null
@ -283,9 +274,7 @@ object ImageUtils {
true true
) )
} else { } else {
Bitmap.createScaledBitmap( this.scale(width, height)
this, width, height, true
)
} }
} }

View File

@ -58,13 +58,12 @@ import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp 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.Metadata
import ru.tech.imageresizershrinker.core.domain.image.model.MetadataTag 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.R
import ru.tech.imageresizershrinker.core.resources.icons.Exif 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.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.EnhancedAlertDialog
import ru.tech.imageresizershrinker.core.ui.widget.enhanced.EnhancedBottomSheetDefaults import ru.tech.imageresizershrinker.core.ui.widget.enhanced.EnhancedBottomSheetDefaults
import ru.tech.imageresizershrinker.core.ui.widget.enhanced.EnhancedButton 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.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.core.net.toUri import androidx.core.net.toUri
import androidx.exifinterface.media.ExifInterface
import com.arkivanov.decompose.ComponentContext import com.arkivanov.decompose.ComponentContext
import dagger.assisted.Assisted import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory import dagger.assisted.AssistedFactory

View File

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

View File

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

View File

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

View File

@ -25,7 +25,6 @@ import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.graphics.toArgb
import androidx.core.net.toUri import androidx.core.net.toUri
import androidx.exifinterface.media.ExifInterface
import coil3.transform.Transformation import coil3.transform.Transformation
import com.arkivanov.decompose.ComponentContext import com.arkivanov.decompose.ComponentContext
import com.t8rin.opencv_tools.image_comparison.ImageDiffTool 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.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.core.net.toUri import androidx.core.net.toUri
import androidx.exifinterface.media.ExifInterface
import com.arkivanov.decompose.ComponentContext import com.arkivanov.decompose.ComponentContext
import com.smarttoolfactory.cropper.model.AspectRatio import com.smarttoolfactory.cropper.model.AspectRatio
import com.smarttoolfactory.cropper.model.OutlineType 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.ImageGetter
import ru.tech.imageresizershrinker.core.domain.image.ImageScaler import ru.tech.imageresizershrinker.core.domain.image.ImageScaler
import ru.tech.imageresizershrinker.core.domain.image.ShareProvider 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.image.model.MetadataTag
import ru.tech.imageresizershrinker.core.domain.saving.FileController import ru.tech.imageresizershrinker.core.domain.saving.FileController
import ru.tech.imageresizershrinker.core.domain.saving.FilenameCreator import ru.tech.imageresizershrinker.core.domain.saving.FilenameCreator
@ -156,11 +157,7 @@ class DeleteExifComponent @AssistedInject internal constructor(
imageGetter.getImage(uri.toString()) imageGetter.getImage(uri.toString())
}.getOrNull()?.let { }.getOrNull()?.let {
val metadata = if (selectedTags.isNotEmpty()) { val metadata = if (selectedTags.isNotEmpty()) {
it.metadata?.apply { it.metadata?.clearAttributes(selectedTags)
selectedTags.forEach { tag ->
setAttribute(tag.key, null)
}
}
} else null } else null
results.add( results.add(
@ -254,11 +251,7 @@ class DeleteExifComponent @AssistedInject internal constructor(
uri.toString() uri.toString()
)?.let { )?.let {
val metadata = if (selectedTags.isNotEmpty()) { val metadata = if (selectedTags.isNotEmpty()) {
it.metadata?.apply { it.metadata?.clearAttributes(selectedTags)
selectedTags.forEach { tag ->
setAttribute(tag.key, null)
}
}
} else null } else null
shareProvider.cacheData( shareProvider.cacheData(

View File

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

View File

@ -46,7 +46,7 @@ import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.unit.LayoutDirection import androidx.compose.ui.unit.LayoutDirection
import androidx.core.content.res.ResourcesCompat import androidx.core.content.res.ResourcesCompat
import androidx.core.graphics.applyCanvas import androidx.core.graphics.applyCanvas
import androidx.exifinterface.media.ExifInterface import androidx.core.graphics.createBitmap
import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.android.qualifiers.ApplicationContext
import ru.tech.imageresizershrinker.core.data.utils.density import ru.tech.imageresizershrinker.core.data.utils.density
import ru.tech.imageresizershrinker.core.data.utils.safeConfig import ru.tech.imageresizershrinker.core.data.utils.safeConfig
@ -92,11 +92,7 @@ internal class AndroidImageDrawApplier @Inject constructor(
} }
is DrawBehavior.Background -> { is DrawBehavior.Background -> {
Bitmap.createBitmap( createBitmap(drawBehavior.width, drawBehavior.height).apply {
drawBehavior.width,
drawBehavior.height,
Bitmap.Config.ARGB_8888
).apply {
val canvas = Canvas(this) val canvas = Canvas(this)
val paint = NativePaint().apply { val paint = NativePaint().apply {
color = drawBehavior.color color = drawBehavior.color
@ -192,10 +188,9 @@ internal class AndroidImageDrawApplier @Inject constructor(
val filter = filterProvider.filterToTransformation( val filter = filterProvider.filterToTransformation(
createFilter<Triple<ImageModel, Float, Int>, Filter.SpotHeal>( createFilter<Triple<ImageModel, Float, Int>, Filter.SpotHeal>(
Triple( Triple(
first = Bitmap.createBitmap( first = createBitmap(
canvasSize.width, canvasSize.width,
canvasSize.height, canvasSize.height
Bitmap.Config.ARGB_8888
).applyCanvas { ).applyCanvas {
drawColor(Color.Black.toArgb()) drawColor(Color.Black.toArgb())
drawPath( drawPath(
@ -531,7 +526,7 @@ internal class AndroidImageDrawApplier @Inject constructor(
private fun Bitmap.overlay(overlay: Bitmap): Bitmap { private fun Bitmap.overlay(overlay: Bitmap): Bitmap {
val image = this val image = this
val config = safeConfig.toSoftware() 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) val canvas = Canvas(finalBitmap)
canvas.drawBitmap(image, Matrix(), null) canvas.drawBitmap(image, Matrix(), null)
canvas.drawBitmap(overlay.toSoftware(), 0f, 0f, 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.Path
import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.graphics.toArgb
import androidx.core.net.toUri import androidx.core.net.toUri
import androidx.exifinterface.media.ExifInterface
import com.arkivanov.decompose.ComponentContext import com.arkivanov.decompose.ComponentContext
import com.arkivanov.decompose.childContext import com.arkivanov.decompose.childContext
import dagger.assisted.Assisted 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.ImageGetter
import ru.tech.imageresizershrinker.core.domain.image.Metadata import ru.tech.imageresizershrinker.core.domain.image.Metadata
import ru.tech.imageresizershrinker.core.domain.image.ShareProvider 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.ImageFormat
import ru.tech.imageresizershrinker.core.domain.image.model.MetadataTag import ru.tech.imageresizershrinker.core.domain.image.model.MetadataTag
import ru.tech.imageresizershrinker.core.domain.saving.FileController import ru.tech.imageresizershrinker.core.domain.saving.FileController
@ -160,13 +161,8 @@ class EditExifComponent @AssistedInject internal constructor(
} }
fun clearExif() { fun clearExif() {
val tempExif = _exif.value val tempExif = _exif.value?.clearAllAttributes()
MetadataTag.entries.forEach { _exif.update { tempExif }
tempExif?.setAttribute(it.key, null)
}
_exif.update {
tempExif
}
registerChanges() registerChanges()
} }
@ -177,7 +173,7 @@ class EditExifComponent @AssistedInject internal constructor(
fun removeExifTag(tag: MetadataTag) { fun removeExifTag(tag: MetadataTag) {
val exifInterface = _exif.value val exifInterface = _exif.value
exifInterface?.setAttribute(tag.key, null) exifInterface?.clearAttribute(tag)
updateExif(exifInterface) updateExif(exifInterface)
} }
@ -186,7 +182,7 @@ class EditExifComponent @AssistedInject internal constructor(
value: String, value: String,
) { ) {
val exifInterface = _exif.value val exifInterface = _exif.value
exifInterface?.setAttribute(tag.key, value) exifInterface?.setAttribute(tag, value)
updateExif(exifInterface) updateExif(exifInterface)
} }

View File

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

View File

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

View File

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

View File

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

View File

@ -18,7 +18,6 @@
package ru.tech.imageresizershrinker.feature.filters.data.model package ru.tech.imageresizershrinker.feature.filters.data.model
import android.graphics.Bitmap import android.graphics.Bitmap
import androidx.exifinterface.media.ExifInterface
import com.t8rin.opencv_tools.spot_heal.SpotHealer import com.t8rin.opencv_tools.spot_heal.SpotHealer
import dagger.assisted.Assisted import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory 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.Color
import androidx.compose.ui.graphics.Path import androidx.compose.ui.graphics.Path
import androidx.core.net.toUri import androidx.core.net.toUri
import androidx.exifinterface.media.ExifInterface
import coil3.transform.Transformation import coil3.transform.Transformation
import com.arkivanov.decompose.ComponentContext import com.arkivanov.decompose.ComponentContext
import com.arkivanov.decompose.childContext 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.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.core.net.toUri import androidx.core.net.toUri
import androidx.exifinterface.media.ExifInterface
import com.arkivanov.decompose.ComponentContext import com.arkivanov.decompose.ComponentContext
import dagger.assisted.Assisted import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory import dagger.assisted.AssistedFactory

View File

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

View File

@ -25,7 +25,6 @@ import androidx.compose.runtime.MutableState
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.exifinterface.media.ExifInterface
import com.arkivanov.decompose.ComponentContext import com.arkivanov.decompose.ComponentContext
import dagger.assisted.Assisted import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory 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.ShaderBrush
import androidx.compose.ui.graphics.TileMode import androidx.compose.ui.graphics.TileMode
import androidx.core.net.toUri import androidx.core.net.toUri
import androidx.exifinterface.media.ExifInterface
import coil3.transform.Transformation import coil3.transform.Transformation
import com.arkivanov.decompose.ComponentContext import com.arkivanov.decompose.ComponentContext
import dagger.assisted.Assisted import dagger.assisted.Assisted

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -22,7 +22,6 @@ import android.graphics.Bitmap
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.graphics.toArgb
import androidx.core.net.toUri import androidx.core.net.toUri
import androidx.exifinterface.media.ExifInterface
import com.awxkee.jxlcoder.JxlAnimatedEncoder import com.awxkee.jxlcoder.JxlAnimatedEncoder
import com.awxkee.jxlcoder.JxlAnimatedImage import com.awxkee.jxlcoder.JxlAnimatedImage
import com.awxkee.jxlcoder.JxlChannelsConfiguration 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.getValue
import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.exifinterface.media.ExifInterface
import com.arkivanov.decompose.ComponentContext import com.arkivanov.decompose.ComponentContext
import dagger.assisted.Assisted import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory import dagger.assisted.AssistedFactory

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -26,7 +26,6 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.exifinterface.media.ExifInterface
import com.arkivanov.decompose.ComponentContext import com.arkivanov.decompose.ComponentContext
import com.smarttoolfactory.cropper.model.AspectRatio import com.smarttoolfactory.cropper.model.AspectRatio
import com.smarttoolfactory.cropper.model.OutlineType import com.smarttoolfactory.cropper.model.OutlineType
@ -385,7 +384,7 @@ class RecognizeTextComponent @AssistedInject internal constructor(
sequenceNumber = null, sequenceNumber = null,
metadata = it.metadata?.apply { metadata = it.metadata?.apply {
setAttribute( setAttribute(
MetadataTag.UserComment.key, MetadataTag.UserComment,
txtString.takeIf { it.isNotEmpty() } txtString.takeIf { it.isNotEmpty() }
) )
}, },
@ -771,7 +770,7 @@ class RecognizeTextComponent @AssistedInject internal constructor(
val exif = it.metadata?.apply { val exif = it.metadata?.apply {
setAttribute( setAttribute(
MetadataTag.UserComment.key, MetadataTag.UserComment,
txtString.takeIf { it.isNotEmpty() } 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.ImageTransformer
import ru.tech.imageresizershrinker.core.domain.image.Metadata import ru.tech.imageresizershrinker.core.domain.image.Metadata
import ru.tech.imageresizershrinker.core.domain.image.ShareProvider 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.ImageData
import ru.tech.imageresizershrinker.core.domain.image.model.ImageFormat 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.ImageInfo
@ -519,10 +520,7 @@ class ResizeAndConvertComponent @AssistedInject internal constructor(
fun canShow(): Boolean = bitmap?.let { imagePreviewCreator.canShow(it) } == true fun canShow(): Boolean = bitmap?.let { imagePreviewCreator.canShow(it) } == true
fun clearExif() { fun clearExif() {
val tempExif = _exif.value val tempExif = _exif.value?.clearAllAttributes()
MetadataTag.entries.forEach {
tempExif?.setAttribute(it.key, null)
}
_exif.update { tempExif } _exif.update { tempExif }
} }
@ -533,7 +531,7 @@ class ResizeAndConvertComponent @AssistedInject internal constructor(
fun removeExifTag(tag: MetadataTag) { fun removeExifTag(tag: MetadataTag) {
val exifInterface = _exif.value val exifInterface = _exif.value
exifInterface?.setAttribute(tag.key, null) exifInterface?.clearAttribute(tag)
updateExif(exifInterface) updateExif(exifInterface)
} }
@ -542,7 +540,7 @@ class ResizeAndConvertComponent @AssistedInject internal constructor(
value: String value: String
) { ) {
val exifInterface = _exif.value val exifInterface = _exif.value
exifInterface?.setAttribute(tag.key, value) exifInterface?.setAttribute(tag, value)
updateExif(exifInterface) updateExif(exifInterface)
} }

View File

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

View File

@ -24,7 +24,6 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.graphics.toArgb
import androidx.exifinterface.media.ExifInterface
import com.arkivanov.decompose.ComponentContext import com.arkivanov.decompose.ComponentContext
import com.arkivanov.decompose.value.Value import com.arkivanov.decompose.value.Value
import com.t8rin.dynamic.theme.ColorTuple 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.ImageTransformer
import ru.tech.imageresizershrinker.core.domain.image.Metadata import ru.tech.imageresizershrinker.core.domain.image.Metadata
import ru.tech.imageresizershrinker.core.domain.image.ShareProvider 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.ImageData
import ru.tech.imageresizershrinker.core.domain.image.model.ImageFormat 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.ImageInfo
@ -563,13 +564,8 @@ class SingleEditComponent @AssistedInject internal constructor(
} }
fun clearExif() { fun clearExif() {
val tempExif = _exif.value val tempExif = _exif.value?.clearAllAttributes()
MetadataTag.entries.forEach { _exif.update { tempExif }
tempExif?.setAttribute(it.key, null)
}
_exif.update {
tempExif
}
registerChanges() registerChanges()
} }
@ -580,7 +576,7 @@ class SingleEditComponent @AssistedInject internal constructor(
fun removeExifTag(tag: MetadataTag) { fun removeExifTag(tag: MetadataTag) {
val exifInterface = _exif.value val exifInterface = _exif.value
exifInterface?.setAttribute(tag.key, null) exifInterface?.clearAttribute(tag)
updateExif(exifInterface) updateExif(exifInterface)
} }
@ -589,7 +585,7 @@ class SingleEditComponent @AssistedInject internal constructor(
value: String, value: String,
) { ) {
val exifInterface = _exif.value val exifInterface = _exif.value
exifInterface?.setAttribute(tag.key, value) exifInterface?.setAttribute(tag, value)
updateExif(exifInterface) updateExif(exifInterface)
} }

View File

@ -21,7 +21,6 @@ package ru.tech.imageresizershrinker.feature.svg_maker.data
import android.content.Context import android.content.Context
import android.graphics.Bitmap import android.graphics.Bitmap
import androidx.exifinterface.media.ExifInterface
import com.t8rin.image.toolbox.svg.ImageTracerAndroid import com.t8rin.image.toolbox.svg.ImageTracerAndroid
import com.t8rin.image.toolbox.svg.ImageTracerAndroid.SvgListener import com.t8rin.image.toolbox.svg.ImageTracerAndroid.SvgListener
import dagger.hilt.android.qualifiers.ApplicationContext 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.getValue
import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.exifinterface.media.ExifInterface
import com.arkivanov.decompose.ComponentContext import com.arkivanov.decompose.ComponentContext
import dagger.assisted.Assisted import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory import dagger.assisted.AssistedFactory

View File

@ -27,7 +27,6 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.graphics.toArgb
import androidx.core.content.res.ResourcesCompat import androidx.core.content.res.ResourcesCompat
import androidx.core.graphics.applyCanvas import androidx.core.graphics.applyCanvas
import androidx.exifinterface.media.ExifInterface
import coil3.transform.RoundedCornersTransformation import coil3.transform.RoundedCornersTransformation
import com.watermark.androidwm.WatermarkBuilder import com.watermark.androidwm.WatermarkBuilder
import com.watermark.androidwm.bean.WatermarkImage 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.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.core.net.toUri import androidx.core.net.toUri
import androidx.exifinterface.media.ExifInterface
import coil3.transform.Transformation import coil3.transform.Transformation
import com.arkivanov.decompose.ComponentContext import com.arkivanov.decompose.ComponentContext
import dagger.assisted.Assisted 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.Color
import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.graphics.toArgb
import androidx.core.net.toUri import androidx.core.net.toUri
import androidx.exifinterface.media.ExifInterface
import com.t8rin.awebp.decoder.AnimatedWebpDecoder import com.t8rin.awebp.decoder.AnimatedWebpDecoder
import com.t8rin.awebp.encoder.AnimatedWebpEncoder import com.t8rin.awebp.encoder.AnimatedWebpEncoder
import dagger.hilt.android.qualifiers.ApplicationContext 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.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.core.net.toUri import androidx.core.net.toUri
import androidx.exifinterface.media.ExifInterface
import com.arkivanov.decompose.ComponentContext import com.arkivanov.decompose.ComponentContext
import dagger.assisted.Assisted import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory import dagger.assisted.AssistedFactory

View File

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