mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2025-09-20 14:01:22 +02:00
Moves SVG generation to fetcher (IO) and avoids the use of TrimIndent, which is too slow (2-10ms each) for this context.
This commit is contained in:
@@ -1,11 +1,20 @@
|
|||||||
package com.vitorpamplona.amethyst.ui.components
|
package com.vitorpamplona.amethyst.ui.components
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.net.Uri
|
||||||
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 coil.ImageLoader
|
||||||
|
import coil.decode.DataSource
|
||||||
|
import coil.decode.ImageSource
|
||||||
|
import coil.fetch.Fetcher
|
||||||
|
import coil.fetch.SourceResult
|
||||||
import coil.request.ImageRequest
|
import coil.request.ImageRequest
|
||||||
import java.nio.ByteBuffer
|
import coil.request.Options
|
||||||
|
import okio.Buffer
|
||||||
import java.security.MessageDigest
|
import java.security.MessageDigest
|
||||||
|
import kotlin.time.ExperimentalTime
|
||||||
|
import kotlin.time.measureTimedValue
|
||||||
|
|
||||||
private fun toHex(color: Color): String {
|
private fun toHex(color: Color): String {
|
||||||
val argb = color.toArgb()
|
val argb = color.toArgb()
|
||||||
@@ -40,29 +49,54 @@ private fun svgString(msg: String): String {
|
|||||||
val mouth = mouths[mouthIndex]
|
val mouth = mouths[mouthIndex]
|
||||||
val accessory = accessories[accIndex]
|
val accessory = accessories[accIndex]
|
||||||
|
|
||||||
return """
|
return """<svg id="$hashHex" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 300">
|
||||||
<svg id="$hashHex" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 300">
|
<defs>
|
||||||
<defs>
|
<style>
|
||||||
<style>
|
.cls-bg{fill:${toHex(bgColor)}}.cls-fill-1{fill:${toHex(fgColor)};}.cls-fill-2{fill:${toHex(fgColor)};}
|
||||||
.cls-bg{fill:${toHex(bgColor)}}.cls-fill-1{fill:${toHex(fgColor)};}.cls-fill-2{fill:${toHex(fgColor)};}
|
${body.style}${face.style}${eye.style}${mouth.style}${accessory.style}
|
||||||
${body.style}${face.style}${eye.style}${mouth.style}${accessory.style}
|
</style>
|
||||||
</style>
|
</defs>
|
||||||
</defs>
|
<title>Robohash $hashHex</title>
|
||||||
<title>Robohash $hashHex</title>
|
${background}${body.paths}${face.paths}${eye.paths}${mouth.paths}${accessory.paths}
|
||||||
${background}${body.paths}${face.paths}${eye.paths}${mouth.paths}${accessory.paths}
|
</svg>"""
|
||||||
</svg>
|
|
||||||
""".trimIndent()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class HashImageFetcher(
|
||||||
|
private val context: Context,
|
||||||
|
private val data: Uri
|
||||||
|
) : Fetcher {
|
||||||
|
|
||||||
|
@OptIn(ExperimentalTime::class)
|
||||||
|
override suspend fun fetch(): SourceResult {
|
||||||
|
val (value, elapsed) = measureTimedValue {
|
||||||
|
val source = try {
|
||||||
|
Buffer().apply { write(svgString(data.toString()).toByteArray()) }
|
||||||
|
} finally {
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceResult(
|
||||||
|
source = ImageSource(source, context),
|
||||||
|
mimeType = null,
|
||||||
|
dataSource = DataSource.MEMORY
|
||||||
|
)
|
||||||
|
}
|
||||||
|
println("Elapsed: $elapsed")
|
||||||
|
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
class Factory : Fetcher.Factory<Uri> {
|
||||||
|
override fun create(data: Uri, options: Options, imageLoader: ImageLoader): Fetcher {
|
||||||
|
return HashImageFetcher(options.context, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
object Robohash {
|
object Robohash {
|
||||||
fun imageRequest(context: Context, message: String): ImageRequest {
|
fun imageRequest(context: Context, message: String): ImageRequest {
|
||||||
return ImageRequest
|
return ImageRequest
|
||||||
.Builder(context)
|
.Builder(context)
|
||||||
.data(
|
.data("robohash:$message")
|
||||||
ByteBuffer.wrap(
|
.fetcherFactory(HashImageFetcher.Factory())
|
||||||
svgString(message).toByteArray()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.crossfade(100)
|
.crossfade(100)
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user