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