Fix fever favicon failed to parse when it's SVG (#514)

* 1. WIP: fix failed to parse base64 image when it's svg+xml;
2. fix a type.

* fix some svg drawing improperly

* refactor a little
This commit is contained in:
kid1412621 2024-01-11 17:47:06 +08:00 committed by GitHub
parent 5d1bdfb5f3
commit cd135cd756
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 51 additions and 12 deletions

View File

@ -1,30 +1,69 @@
package me.ash.reader.ui.component.base
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.util.Base64
import androidx.compose.foundation.Image
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.graphics.drawscope.DrawScope
import androidx.compose.ui.graphics.nativeCanvas
import androidx.compose.ui.graphics.painter.Painter
import com.caverock.androidsvg.SVG
@Composable
fun Base64Image(
modifier: Modifier = Modifier,
base64Uri: String
) {
val bitmap = base64ToBitmap(base64Uri)
val imageBitmap = bitmap.asImageBitmap()
val isSvg = base64Uri.startsWith("image/svg")
Image(
bitmap = imageBitmap,
modifier = modifier,
contentDescription = null
)
if (isSvg) {
Image(
painter = base64ToPainter(base64Uri),
modifier = modifier,
contentDescription = null
)
} else {
val bytes = base64ToBytes(base64Uri)
val bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
Image(
bitmap = bitmap.asImageBitmap(),
modifier = modifier,
contentDescription = null
)
}
}
fun base64ToBitmap(base64String: String): Bitmap {
private fun base64ToBytes(base64String: String): ByteArray {
val base64Data = base64String.substringAfter("base64,")
val imageBytes = Base64.decode(base64Data, Base64.DEFAULT)
return BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.size)
return Base64.decode(base64Data, Base64.DEFAULT)
}
@Composable
private fun base64ToPainter(base64Str: String): Painter {
return remember(base64Str) {
val svg = SVG.getFromString(String(base64ToBytes(base64Str)))
object : Painter() {
override val intrinsicSize: Size
get() {
svg.let {
return Size(it.documentWidth, it.documentHeight)
}
}
override fun DrawScope.onDraw() {
svg.let {
val canvas = drawContext.canvas.nativeCanvas
// see: https://code.google.com/archive/p/androidsvg/wikis/FAQ.wiki#my-document-has-a-viewbox-but-it-is-still-not-scaling
svg.setDocumentHeight("100%")
svg.setDocumentWidth("100%")
svg.renderToCanvas(canvas)
}
}
}
}
}

View File

@ -356,7 +356,7 @@
<string name="inoreader" translatable="false">Inoreader</string>
<string name="local_desc">On this device</string>
<string name="services">Services</string>
<string name="feedly_desc" translatable="false">feedll.com</string>
<string name="feedly_desc" translatable="false">feedly.com</string>
<string name="inoreader_desc" translatable="false">inoreader.com</string>
<string name="self_hosted">Self-Hosted</string>
<string name="fresh_rss_desc" translatable="false">freshrss.org</string>