0
0

More than 1 year has passed since last update.

Glide で SVG を表示したい

Last updated at Posted at 2023-05-05

概要

Glide は標準で SVG をサポートしてなかったので試してみました。

基本的にはここに記載されている公式のサンプルソースに書いてあることと同じことをしているだけです。

手順

ライブラリの追加

plugins {
    ...
    id 'com.google.devtools.ksp'
}
android {
    ...
    dependencies {
        ...
        ksp 'com.github.bumptech.glide:ksp:4.15.1'
        implementation 'com.caverock:androidsvg:1.4'
    }
}

以下のファイルを作成する

SvgDecoder.kt
import com.bumptech.glide.load.Options
import com.bumptech.glide.load.ResourceDecoder
import com.bumptech.glide.load.engine.Resource
import com.bumptech.glide.load.resource.SimpleResource
import com.bumptech.glide.request.target.Target
import com.caverock.androidsvg.SVG
import com.caverock.androidsvg.SVGParseException
import java.io.IOException
import java.io.InputStream


/** Decodes an SVG internal representation from an [InputStream].  */
class SvgDecoder : ResourceDecoder<InputStream, SVG> {
    override fun handles(source: InputStream, options: Options): Boolean {
        return true
    }

    @Throws(IOException::class)
    override fun decode(source: InputStream, width: Int, height: Int, options: Options): Resource<SVG> {
        return try {
            val svg = SVG.getFromInputStream(source)
            if (width != Target.SIZE_ORIGINAL) {
                svg.documentWidth = width.toFloat()
            }
            if (height != Target.SIZE_ORIGINAL) {
                svg.documentHeight = height.toFloat()
            }
            SimpleResource(svg)
        } catch (ex: Throwable) {
            throw IOException("Cannot load SVG from stream", ex)
        }
    }
}
SvgDrawableTranscoder.kt
import android.graphics.Picture
import android.graphics.drawable.PictureDrawable
import com.bumptech.glide.load.Options
import com.bumptech.glide.load.engine.Resource
import com.bumptech.glide.load.resource.SimpleResource
import com.bumptech.glide.load.resource.transcode.ResourceTranscoder
import com.caverock.androidsvg.SVG


/**
 * Convert the [SVG]'s internal representation to an Android-compatible one ([Picture]).
 */
class SvgDrawableTranscoder : ResourceTranscoder<SVG, PictureDrawable> {
    override fun transcode(toTranscode: Resource<SVG>, options: Options): Resource<PictureDrawable> {
        val svg = toTranscode.get()
        val picture = svg.renderToPicture()
        val drawable = PictureDrawable(picture)
        return SimpleResource(drawable)
    }
}
SvgModule.kt
import android.content.Context
import android.graphics.drawable.PictureDrawable
import com.bumptech.glide.Glide
import com.bumptech.glide.Registry
import com.bumptech.glide.annotation.GlideModule
import com.bumptech.glide.module.AppGlideModule
import com.caverock.androidsvg.SVG
import java.io.InputStream


/** Module for the SVG sample app.  */
@GlideModule
class SvgModule : AppGlideModule() {
    override fun registerComponents(context: Context, glide: Glide, registry: Registry) {
        registry.register(SVG::class.java, PictureDrawable::class.java, SvgDrawableTranscoder())
            .append(InputStream::class.java, SVG::class.java, SvgDecoder())
    }

    // Disable manifest parsing to avoid adding similar modules twice.
    override fun isManifestParsingEnabled(): Boolean {
        return false
    }
}

あとは使うだけ

Glide.with(context).load("path/to/svg.svg").into(myView)
GlideImage(model = "path/to/svg.svg",contentDescription = "") // Jetpack Compose

公式のソースとの違い

SVG.getFromInputStream の例外を catch (ex: Throwable) として全て catch するようにしているのが公式との違いです。androidsvg は様々な例外を返すので、あまり行儀が良くないSVGファイルを渡すと元のコードではクラッシュすることがあります。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0