Hey I know that I can load a svg file from the fil...
# compose-desktop
j
Hey I know that I can load a svg file from the file system using painterResource, is it possible to display an SVG when e.g. having the raw data as a string?
e
The short answer is no. At least from what I know. The simplest is probably to convert it into an Android vector using Android Studio, and then load it. The SVG format/spec is huge, and the file format is not a binary format, so it can be both heavy to parse and contain unsupoorted tags.
j
converting it via AS is not possible, I get the raw data from an API
e
I guess one solution could be to use Lottie. I don't think there's an API in Compose to use for that use-case.
c
if it's possible to load it from the file system... then wouldn't it be possible to write the raw data to disk and load it that way? As a grotesque stop gap until loading arbitrary svgs in string form is possible
j
yea just thought about security issues, as the SVG file is an QR-Code for 2FA
m
Would this satisfy your needs?
Copy code
fun svgPainter (encodedData: ByteArray, density: Density) : Painter? {
    if (encodedData.isEmpty()) return null
    try {
         return androidx.compose.ui.res.loadSvgPainter(ByteArrayInputStream(encodedData), density)
    } catch (e: Exception) {
        log.error(e) { "Could not load painter for encoded SVG data."  }
        return null
    }
}
I have written a service class for my own purposes which can read SVG from a ByteArray on Android, Desktop and Native (iOS,…). The code above is a fragment from the Desktop implementation. If there is some interest I could also provide the full code.
j
that works perfectly, thanks!
e
I'm a little confused. Where do you find
loadSvgPainter
in https://developer.android.com/reference/kotlin/androidx/compose/ui/res/package-summary ?
m
You are looking at the Android documentation and this
loadSvgPainter
exists only for the desktop version as far as I know. E.g., in order to also support iOS I copied the one from Desktop into my projects iOS source set and with some tiny modification it also works there then because the loader works directly with Skia. For Android I use some other code which makes use of an external library because Skia access is not available on Android.
In order to get that working on iOS too you have to make a one-to-one copy of the desktop androidx.compose.ui.res.SVGPainter and androidx.compose.ui.graphics.vector.DrawCache class. Then you have to modify the loadSvgPainter method to use a ByteArray instead of a Java InputStream.
Copy code
fun loadSvgPainter(
    encodedData: ByteArray,
    density: Density
): Painter {
    val data = Data.makeFromBytes(encodedData)
    return SVGPainter(SVGDOM(data), density)
}
That’s all. I needed these methods because I have to read SVGs from a database and not from a file.
e
oh! now I understand why I didn't find it. Yeah, compose desktop mirror the package names, but adds/removes some features, so looking at the android doc is not always the wisest. Thanks for clarifying.
312 Views