mirror of
https://github.com/T8RIN/ImageToolbox.git
synced 2025-05-17 21:45:59 +08:00
Make metadata realization independent
This commit is contained in:
@ -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
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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()
|
@ -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 = {}
|
||||
|
@ -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
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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(
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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()
|
||||
)
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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(
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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() }
|
||||
)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user