Skip to content

Commit

Permalink
Added ability to edit EXIF without recompression in separate tool by #…
Browse files Browse the repository at this point in the history
  • Loading branch information
T8RIN committed Jan 19, 2025
1 parent 8085320 commit d3de80b
Show file tree
Hide file tree
Showing 33 changed files with 848 additions and 135 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
package ru.tech.imageresizershrinker.core.resources.icons

import androidx.compose.material.icons.Icons
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.path
import androidx.compose.ui.unit.dp

val Icons.Outlined.ExifEdit: ImageVector by lazy {
ImageVector.Builder(
name = "Outlined.ExifEdit",
defaultWidth = 24.dp,
defaultHeight = 24.dp,
viewportWidth = 24f,
viewportHeight = 24f
).apply {
path(fill = SolidColor(Color(0xFF000000))) {
moveTo(17.138f, 9.874f)
lineToRelative(-7.023f, -7.023f)
curveTo(9.803f, 2.539f, 9.413f, 2.383f, 9.023f, 2.383f)
horizontalLineTo(3.561f)
curveTo(2.702f, 2.383f, 2f, 3.085f, 2f, 3.944f)
verticalLineToRelative(5.462f)
curveToRelative(0f, 0.39f, 0.156f, 0.78f, 0.468f, 1.092f)
lineToRelative(7.023f, 7.023f)
curveToRelative(0.312f, 0.312f, 0.702f, 0.468f, 1.092f, 0.468f)
reflectiveCurveToRelative(0.78f, -0.156f, 1.092f, -0.468f)
lineToRelative(5.462f, -5.462f)
curveToRelative(0.312f, -0.312f, 0.468f, -0.702f, 0.468f, -1.092f)
curveTo(17.606f, 10.576f, 17.45f, 10.186f, 17.138f, 9.874f)
close()
moveTo(10.584f, 16.429f)
lineToRelative(-7.023f, -7.023f)
verticalLineTo(3.944f)
horizontalLineTo(9.023f)
lineToRelative(7.023f, 7.023f)
lineTo(10.584f, 16.429f)
close()
}
path(fill = SolidColor(Color(0xFF000000))) {
moveTo(5.322f, 4.724f)
curveToRelative(0.523f, 0f, 0.981f, 0.458f, 0.981f, 0.981f)
reflectiveCurveTo(5.845f, 6.686f, 5.322f, 6.686f)
reflectiveCurveTo(4.341f, 6.228f, 4.341f, 5.705f)
reflectiveCurveTo(4.799f, 4.724f, 5.322f, 4.724f)
}
path(fill = SolidColor(Color(0xFF000000))) {
moveTo(9.605f, 12.27f)
lineToRelative(-0.576f, -0.576f)
lineToRelative(2.302f, -2.302f)
lineToRelative(0.576f, 0.576f)
lineToRelative(-2.302f, 2.302f)
}
path(fill = SolidColor(Color(0xFF000000))) {
moveTo(13.058f, 12.27f)
lineToRelative(-0.576f, -0.576f)
lineToRelative(-0.384f, 0.384f)
lineToRelative(0.576f, 0.576f)
lineToRelative(-0.576f, 0.576f)
lineToRelative(-0.576f, -0.576f)
lineToRelative(-0.767f, 0.767f)
lineToRelative(-0.576f, -0.576f)
lineToRelative(2.302f, -2.302f)
lineToRelative(1.151f, 1.151f)
close()
}
path(fill = SolidColor(Color(0xFF000000))) {
moveTo(8.117f, 7.329f)
lineToRelative(0.576f, 0.576f)
lineToRelative(0.576f, -0.576f)
lineToRelative(-0.576f, -0.576f)
lineToRelative(-0.576f, -0.576f)
lineToRelative(-0.904f, 0.904f)
lineToRelative(-0.495f, 0.495f)
lineToRelative(-0.904f, 0.904f)
lineToRelative(0.576f, 0.576f)
lineToRelative(0.576f, 0.576f)
lineToRelative(0.576f, -0.576f)
lineToRelative(-0.576f, -0.576f)
lineToRelative(0.192f, -0.192f)
lineToRelative(0.136f, -0.136f)
lineToRelative(0.576f, 0.576f)
lineToRelative(0.495f, -0.495f)
lineToRelative(-0.576f, -0.576f)
lineToRelative(0.136f, -0.136f)
close()
}
path(fill = SolidColor(Color(0xFF000000))) {
moveTo(9.612f, 7.659f)
lineTo(8.917f, 9.28f)
lineTo(7.295f, 9.975f)
lineToRelative(0.463f, 0.463f)
lineToRelative(0.811f, -0.347f)
lineToRelative(-0.347f, 0.811f)
lineToRelative(0.463f, 0.463f)
lineToRelative(0.695f, -1.621f)
lineToRelative(1.621f, -0.695f)
lineToRelative(-0.463f, -0.463f)
lineTo(9.728f, 8.933f)
lineToRelative(0.347f, -0.811f)
lineTo(9.612f, 7.659f)
close()
}
path(fill = SolidColor(Color(0xFF000000))) {
moveTo(21.886f, 14.399f)
curveToRelative(-0.076f, -0.186f, -0.182f, -0.355f, -0.317f, -0.507f)
lineToRelative(-0.937f, -0.937f)
curveToRelative(-0.152f, -0.152f, -0.321f, -0.266f, -0.507f, -0.342f)
curveTo(19.94f, 12.538f, 19.746f, 12.5f, 19.543f, 12.5f)
curveToRelative(-0.186f, 0f, -0.371f, 0.034f, -0.557f, 0.101f)
curveToRelative(-0.186f, 0.068f, -0.355f, 0.177f, -0.507f, 0.329f)
lineToRelative(-5.293f, 5.268f)
curveToRelative(-0.101f, 0.101f, -0.177f, 0.215f, -0.228f, 0.342f)
reflectiveCurveToRelative(-0.076f, 0.258f, -0.076f, 0.393f)
verticalLineToRelative(1.671f)
curveToRelative(0f, 0.287f, 0.097f, 0.528f, 0.291f, 0.722f)
curveToRelative(0.194f, 0.194f, 0.435f, 0.291f, 0.722f, 0.291f)
horizontalLineToRelative(1.671f)
curveToRelative(0.135f, 0f, 0.266f, -0.025f, 0.392f, -0.076f)
curveToRelative(0.127f, -0.051f, 0.241f, -0.127f, 0.342f, -0.228f)
lineToRelative(5.268f, -5.268f)
curveToRelative(0.152f, -0.152f, 0.262f, -0.325f, 0.329f, -0.519f)
curveTo(21.966f, 15.332f, 22f, 15.142f, 22f, 14.957f)
reflectiveCurveTo(21.962f, 14.585f, 21.886f, 14.399f)
close()
moveTo(15.365f, 20.098f)
horizontalLineTo(14.402f)
verticalLineToRelative(-0.962f)
lineToRelative(3.09f, -3.064f)
lineToRelative(0.481f, 0.456f)
lineToRelative(0.456f, 0.481f)
lineTo(15.365f, 20.098f)
close()
}
}.build()
}
3 changes: 3 additions & 0 deletions core/resources/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1560,4 +1560,7 @@
<string name="pages_selection">Pages Selection</string>
<string name="tool_exit_confirmation">Tool Exit Confirmation</string>
<string name="tool_exit_confirmation_sub">If you have unsaved changes while using particular tools and try to close it, then confirm dialog will be shown</string>
<string name="edit_exif_screen">Edit EXIF</string>
<string name="edit_exif_screen_sub">Change metadata of single image without recompression</string>
<string name="edit_exif_tag">Tap to edit available tags</string>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,13 @@ fun rememberClipboardText(): State<String> {
return clip
}

fun ClipboardManager?.clipList(): List<Uri> = this?.primaryClip?.clipList() ?: emptyList()
fun ClipboardManager?.clipList(): List<Uri> = runCatching {
this?.primaryClip?.clipList()
}.getOrNull() ?: emptyList()

fun ClipboardManager?.clipText(): String = this?.primaryClip?.getItemAt(0)?.text?.toString() ?: ""
fun ClipboardManager?.clipText(): String = runCatching {
this?.primaryClip?.getItemAt(0)?.text?.toString()
}.getOrNull() ?: ""

fun ClipData.clipList() = List(
size = itemCount,
Expand All @@ -123,12 +127,15 @@ fun ClipData.clipList() = List(
}
).filterNotNull()

fun List<Uri>.toClipData(): ClipData? {
fun List<Uri>.toClipData(
description: String = "Images"
): ClipData? {
if (this.isEmpty()) return null

return ClipData(
ClipDescription(
"Images", arrayOf("image/*")
description,
arrayOf("image/*")
),
ClipData.Item(this.first())
).apply {
Expand All @@ -139,11 +146,12 @@ fun List<Uri>.toClipData(): ClipData? {
}

fun Uri.asClip(
context: Context
context: Context,
label: String = "Image"
): ClipEntry = ClipEntry(
ClipData.newUri(
context.contentResolver,
"IMAGE",
label,
this
)
)
Original file line number Diff line number Diff line change
Expand Up @@ -710,78 +710,102 @@ sealed class Screen(
subtitle = 0
)

@Serializable
data class EditExif(
val uri: KUri? = null,
) : Screen(
id = 37,
title = R.string.edit_exif_screen,
subtitle = R.string.edit_exif_screen_sub
)

companion object {
val typedEntries by lazy {
listOf(
listOf(
SingleEdit(),
ResizeAndConvert(),
FormatConversion(),
Crop(),
WeightResize(),
LimitResize(),
DeleteExif(),
) to Triple(
R.string.edit,
Icons.Rounded.MiniEditLarge,
Icons.Outlined.MiniEditLarge
ScreenGroup(
entries = listOf(
SingleEdit(),
ResizeAndConvert(),
FormatConversion(),
Crop(),
WeightResize(),
LimitResize(),
EditExif(),
DeleteExif(),
),
title = R.string.edit,
selectedIcon = Icons.Rounded.MiniEditLarge,
baseIcon = Icons.Outlined.MiniEditLarge
),
listOf(
Filter(),
Draw(),
EraseBackground(),
MarkupLayers(),
CollageMaker(),
ImageStitching(),
ImageStacking(),
ImageSplitting(),
Watermarking(),
GradientMaker(),
NoiseGeneration,
) to Triple(
R.string.create,
Icons.Filled.AutoAwesome,
Icons.Outlined.AutoAwesome
ScreenGroup(
entries = listOf(
Filter(),
Draw(),
EraseBackground(),
MarkupLayers(),
CollageMaker(),
ImageStitching(),
ImageStacking(),
ImageSplitting(),
Watermarking(),
GradientMaker(),
NoiseGeneration,
),
title = R.string.create,
selectedIcon = Icons.Filled.AutoAwesome,
baseIcon = Icons.Outlined.AutoAwesome
),
listOf(
PickColorFromImage(),
RecognizeText(),
Compare(),
ImagePreview(),
Base64Tools(),
SvgMaker(),
GeneratePalette(),
LoadNetImage(),
) to Triple(
R.string.image,
Icons.Filled.FilterHdr,
Icons.Outlined.FilterHdr
ScreenGroup(
entries = listOf(
PickColorFromImage(),
RecognizeText(),
Compare(),
ImagePreview(),
Base64Tools(),
SvgMaker(),
GeneratePalette(),
LoadNetImage(),
),
title = R.string.image,
selectedIcon = Icons.Filled.FilterHdr,
baseIcon = Icons.Outlined.FilterHdr
),
listOf(
PdfTools(),
DocumentScanner,
ScanQrCode(),
ColorTools,
GifTools(),
Cipher(),
ChecksumTools(),
Zip(),
JxlTools(),
ApngTools(),
WebpTools()
) to Triple(
R.string.tools,
Icons.Rounded.Toolbox,
Icons.Outlined.Toolbox
ScreenGroup(
entries = listOf(
PdfTools(),
DocumentScanner,
ScanQrCode(),
ColorTools,
GifTools(),
Cipher(),
ChecksumTools(),
Zip(),
JxlTools(),
ApngTools(),
WebpTools()
),
title = R.string.tools,
selectedIcon = Icons.Rounded.Toolbox,
baseIcon = Icons.Outlined.Toolbox
)
)
}

val entries by lazy {
typedEntries.flatMap { it.first }.sortedBy { it.id }
typedEntries.flatMap { it.entries }.sortedBy { it.id }
}

const val FEATURES_COUNT = 60
const val FEATURES_COUNT = 61
}
}

data class ScreenGroup(
val entries: List<Screen>,
@StringRes val title: Int,
val selectedIcon: ImageVector,
val baseIcon: ImageVector
) {
fun icon(isSelected: Boolean) = if (isSelected) selectedIcon else baseIcon
}

private typealias KUri = @Serializable(UriSerializer::class) Uri
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import ru.tech.imageresizershrinker.core.resources.icons.CropSmall
import ru.tech.imageresizershrinker.core.resources.icons.Draw
import ru.tech.imageresizershrinker.core.resources.icons.Encrypted
import ru.tech.imageresizershrinker.core.resources.icons.Exif
import ru.tech.imageresizershrinker.core.resources.icons.ExifEdit
import ru.tech.imageresizershrinker.core.resources.icons.ImageCombine
import ru.tech.imageresizershrinker.core.resources.icons.ImageConvert
import ru.tech.imageresizershrinker.core.resources.icons.ImageDownload
Expand Down Expand Up @@ -111,6 +112,7 @@ internal fun Screen.simpleName(): String? = when (this) {
is Screen.Base64Tools -> "Base64_Tools"
is Screen.ChecksumTools -> "Checksum_Tools"
is Screen.MeshGradients -> "Mesh_Gradients"
is Screen.EditExif -> "Edit_EXIF"
}

internal fun Screen.icon(): ImageVector? = when (this) {
Expand Down Expand Up @@ -157,6 +159,7 @@ internal fun Screen.icon(): ImageVector? = when (this) {
is Screen.MarkupLayers -> Icons.Outlined.Stack
is Screen.Base64Tools -> Icons.Outlined.Base64
is Screen.ChecksumTools -> Icons.Rounded.Tag
is Screen.EditExif -> Icons.Outlined.ExifEdit
}

internal object UriSerializer : KSerializer<Uri> {
Expand Down
Loading

0 comments on commit d3de80b

Please sign in to comment.