Glide有加载PNG和SVG的方法吗?

Mau*_*ker 20 java svg android android-glide

我使用滑翔到一些图像加载异步到一些我的ImageViewS,我知道它能够处理图像像PNG或者JPG因为它可以处理SVG.

事实是,据我所知,我加载这两种图像的方式不同.喜欢:

加载"正常"图像

Glide.with(mContext)
                .load("URL")
                .into(cardHolder.iv_card);
Run Code Online (Sandbox Code Playgroud)

加载SVG

GenericRequestBuilder<Uri, InputStream, SVG, PictureDrawable> requestBuilder = Glide.with(mContext)
        .using(Glide.buildStreamModelLoader(Uri.class, mContext), InputStream.class)
        .from(Uri.class)
        .as(SVG.class)
        .transcode(new SvgDrawableTranscoder(), PictureDrawable.class)
        .sourceEncoder(new StreamEncoder())
        .cacheDecoder(new FileToStreamDecoder<>(new SVGDecoder()))
        .decoder(new SVGDecoder())
        .listener(new SvgSoftwareLayerSetter<Uri>());

requestBuilder
        .diskCacheStrategy(DiskCacheStrategy.NONE)
        .load(Uri.parse("URL"))
        .into(cardHolder.iv_card);
Run Code Online (Sandbox Code Playgroud)

如果我尝试使用第一种方法加载SVG,它将无法工作.如果我尝试使用第二种方法加载PNG或JPG,它也无法正常工作.

是否有使用Glide加载两种图像类型的通用方法?

我从中获取这些图像的服务器在下载之前不会告诉我图像类型.它是一个REST服务器,资源将以类似的方式检索"http://foo.bar/resource".了解图像类型的唯一方法是读取HEAD响应.

Mah*_*ade 16

您可以将GlideAndroidSVG结合使用来实现您的目标.

有来自Glide for SVG的样本.示例示例

设置RequestBuilder

requestBuilder = Glide.with(mActivity)
    .using(Glide.buildStreamModelLoader(Uri.class, mActivity), InputStream.class)
    .from(Uri.class)
    .as(SVG.class)
    .transcode(new SvgDrawableTranscoder(), PictureDrawable.class)
    .sourceEncoder(new StreamEncoder())
    .cacheDecoder(new FileToStreamDecoder<SVG>(new SvgDecoder()))
    .decoder(new SvgDecoder())
    .placeholder(R.drawable.ic_facebook)
    .error(R.drawable.ic_web)
    .animate(android.R.anim.fade_in)
    .listener(new SvgSoftwareLayerSetter<Uri>());
Run Code Online (Sandbox Code Playgroud)

将RequestBuilder与uri一起使用

Uri uri = Uri.parse("http://upload.wikimedia.org/wikipedia/commons/e/e8/Svg_example3.svg");
requestBuilder
    .diskCacheStrategy(DiskCacheStrategy.SOURCE)
    // SVG cannot be serialized so it's not worth to cache it
    .load(uri)
    .into(mImageView);
Run Code Online (Sandbox Code Playgroud)

这样您就可以实现目标.我希望这是有帮助的.

  • 没有`.using()` (3认同)
  • 从 URL 你可以找到图像是 SVG 或 PNG 然后将它重定向到特定的 requestBuilder (2认同)
  • 您正在使用右侧URL从服务器下载图像,您知道URL (2认同)
  • 让我们[在聊天中继续讨论](http://chat.stackoverflow.com/rooms/103968/discussion-between-mauker-and-maheshwar-ligade)。 (2认同)

Sad*_*egh 16

替代方式:kotlin + 线圈

该解决方案适用于 .svg 、 .png 、 .jpg

添加依赖:

//Coil (https://github.com/coil-kt/coil)
implementation("io.coil-kt:coil:2.5.0")
implementation("io.coil-kt:coil-svg:2.5.0")
Run Code Online (Sandbox Code Playgroud)

将此函数添加到您的代码中:

fun ImageView.loadUrl(url: String) {
    val imageLoader = ImageLoader.Builder(context)
        .components { add(SvgDecoder.Factory()) }
        .build()

    val request = ImageRequest.Builder(context)
        .crossfade(true)
        .crossfade(500)
        .placeholder(R.drawable.placeholder)
        .error(R.drawable.error)
        .data(url)
        .target(this)
        .build()

    imageLoader.enqueue(request)
}
Run Code Online (Sandbox Code Playgroud)

然后在您的活动或片段中调用此方法:

  imageView.loadUrl(url)
  // Sample SVG url : https://upload.wikimedia.org/wikipedia/commons/3/36/Red_jungle_fowl_white_background.png
Run Code Online (Sandbox Code Playgroud)


小智 8

我添加了一个灵活的解码管道来解码图像或 SVG,也许可以提供帮助!基于滑动 SVG 示例

解码器

class SvgOrImageDecoder : ResourceDecoder<InputStream, SvgOrImageDecodedResource> {

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<SvgOrImageDecodedResource>? {
    val array = source.readBytes()
    val svgInputStream = ByteArrayInputStream(array.clone())
    val pngInputStream = ByteArrayInputStream(array.clone())

    return try {
        val svg = SVG.getFromInputStream(svgInputStream)

        try {
            source.close()
            pngInputStream.close()
        } catch (e: IOException) {}

        SimpleResource(SvgOrImageDecodedResource(svg))
    } catch (ex: SVGParseException) {
        try {
            val bitmap = BitmapFactory.decodeStream(pngInputStream)
            SimpleResource(SvgOrImageDecodedResource(bitmap = bitmap))
        } catch (exception: Exception){
            try {
                source.close()
                pngInputStream.close()
            } catch (e: IOException) {}
            throw IOException("Cannot load SVG or Image from stream", ex)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

转码器

class SvgOrImageDrawableTranscoder : ResourceTranscoder<SvgOrImageDecodedResource, PictureDrawable> {
override fun transcode(
    toTranscode: Resource<SvgOrImageDecodedResource>,
    options: Options
): Resource<PictureDrawable>? {
    val data = toTranscode.get()

    if (data.svg != null) {
        val picture = data.svg.renderToPicture()
        val drawable = PictureDrawable(picture)
        return SimpleResource(drawable)
    } else if (data.bitmap != null)
        return SimpleResource(PictureDrawable(renderToPicture(data.bitmap)))
    else return null
}

private fun renderToPicture(bitmap: Bitmap): Picture{
    val picture = Picture()
    val canvas = picture.beginRecording(bitmap.width, bitmap.height)
    canvas.drawBitmap(bitmap, null, RectF(0f, 0f, bitmap.width.toFloat(), bitmap.height.toFloat()), null)
    picture.endRecording();

    return picture
}
Run Code Online (Sandbox Code Playgroud)

解码资源

data class SvgOrImageDecodedResource(
val svg:SVG? = null,
val bitmap: Bitmap? = null)
Run Code Online (Sandbox Code Playgroud)

滑翔模块

class AppGlideModule : AppGlideModule() {
override fun registerComponents(
    context: Context, glide: Glide, registry: Registry
) {
    registry.register(SvgOrImageDecodedResource::class.java, PictureDrawable::class.java, SvgOrImageDrawableTranscoder())
        .append(InputStream::class.java, SvgOrImageDecodedResource::class.java, SvgOrImageDecoder())
}

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

}