Glide 是否有同时加载 PNG 和 SVG 的方法?

Does Glide have a method for loading both PNG and SVG?

我正在使用 Glide 将一些图像 异步加载 到我的一些 ImageView 中,我知道它可以处理像 PNGJPG 因为它可以处理 SVG

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

正在加载 "normal" 图片

Glide.with(mContext)
                .load("URL")
                .into(cardHolder.iv_card);

正在加载 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);

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

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

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

您可以一起使用 Glide & AndroidSVG 来实现您的目标。

有来自 Glide 的 SVG 示例。Sample Example

Setup 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>());

Use RequestBuilder with 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);

这样你就可以实现你的目标了。希望对您有所帮助。

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

Decoder

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)
        }
    }
}

Transcoder

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
}

Decoded Resource

data class SvgOrImageDecodedResource(
val svg:SVG? = null,
val bitmap: Bitmap? = null)

Glide Module

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
}

}

对于因为正在寻找在 Xamarin Android 中加载 SVG 的方法而访问此线程的其他人,接受的答案将不起作用,因为其中很多 类 / 方法不' 似乎在 Xamarin Glide nuget 包中可用。这是对我有用的:

public static void SetSvgFromBytes (this ImageView imageView, byte[] bytes, int width, int height) {
            // Load the SVG from the bytes.
            var stream = new MemoryStream (bytes);
            var svg = SVG.GetFromInputStream (stream);
            // Create a Bitmap to render our SVG to.
            var bitmap = Bitmap.CreateBitmap (width, height, Bitmap.Config.Argb8888);
            // Create a Canvas to use for rendering.
            var canvas = new Canvas (bitmap);
            canvas.DrawRGB (255, 255, 255);
            // Now render the SVG to the Canvas.
            svg.RenderToCanvas (canvas);
            // Finally, populate the imageview from the Bitmap.
            imageView.SetImageBitmap (bitmap);
        }

它需要 AndroidSVG.Xamarin nuget 包。

对于 Glide 4+,使用这个名为 GlideToVectorYou 的库,它在内部使用 Glide。

fun ImageView.loadSvg(url: String?) {
    GlideToVectorYou
        .init()
        .with(this.context)
        .setPlaceHolder(R.drawable.loading, R.drawable.actual)
        .load(Uri.parse(url), this)
}

来源:

我也遇到了同样的问题我所做的解决了我的问题你只需要做两件事就可以完美地工作 转到 link https://github.com/corouteam/GlideToVectorYou 1-只需将过去的 Maven 依赖项复制到项目构建 所有项目{ 存储库{ ... maven { url 'https://jitpack.io' } } } 2-在应用程序构建中添加依赖项 喜欢实施 'com.github.corouteam:GlideToVectorYou:v2.0.0'

谢谢它会决定加载 svg 确保你加载的和我一样

Glide.with(holder.itemView.getContext()) .load(图片url) .apply(新请求选项() .placeholder(R.drawable.placeholder) .dontAnimate() .fitCenter()) .into(holder.image);

如果有人仍然需要它,使用 Glide v4,您可以使用 Glide-SVG 库轻松地向 Glide 添加 SVG 支持。 你也只需要导入 Android SVG 库,然后你可以使用这个简单的标准代码行使用 Glide 渲染任何 SVG:

GlideApp.with(this).load(url).into(imageView)

其中 GlideApp 是您本地生成的 Glide Module,如下所示:

@GlideModule
class GlideModule : AppGlideModule() {
    override fun isManifestParsingEnabled() = false

    override fun applyOptions(context: Context, builder: GlideBuilder) {
        super.applyOptions(context, builder)
        builder.setLogLevel(Log.DEBUG)
    }
}

GlideToVector你没有为我工作,所以我用了coil和coil-svg扩展库

替代方式:kotlin + Coil

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

添加依赖:

//Coil (https://github.com/coil-kt/coil)
implementation("io.coil-kt:coil:1.2.0")
implementation("io.coil-kt:coil-svg:1.2.0")

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

fun ImageView.loadUrl(url: String) {

val imageLoader = ImageLoader.Builder(this.context)
    .componentRegistry { add(SvgDecoder(this@loadUrl.context)) }
    .build()

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

imageLoader.enqueue(request)
}

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

  imageView.loadUrl(url)
  // url example : https://upload.wikimedia.org/wikipedia/commons/3/36/Red_jungle_fowl_white_background.png

使用 Sharp 库代替 Glide 库

implementation 'com.pixplicity.sharp:library:1.1.0'

InputStream stream = response.body().byteStream();
                   Sharp.loadInputStream(stream).into(target);
                    stream.close();  

可以在这里看到一个例子https://www.geeksforgeeks.org/how-to-load-svg-from-url-in-android-imageview/

fun fetchSvg(context: Context, url: String, target: ImageView) {
    val httpClient = OkHttpClient.Builder()
        .cache(Cache(context.cacheDir, 5 * 1024 * 1014))
        .build()
 
    val request: Request = Request.Builder().url(url).build()
    httpClient.newCall(request).enqueue(object : Callback {
        override fun onFailure(call: Call?, e: IOException?) {
            // we are adding a default image if we gets any error.
            target.setImageResource(R.drawable.ic_app_logo)
        }

        @Throws(IOException::class)
        override fun onResponse(call: Call?, response: Response) {
       
            response.body()?.apply {
                val stream = this.byteStream()
                Sharp.loadInputStream(stream).into(target)
                stream.close()
            }
        }
    })
}

使用代码

 if(item.logo.endsWith("svg"))
               Media.fetchSvg(icon.context,item.logo, icon)
            else{
               Glide.with(icon.context).load(Uri.parse(item.logo)).into(icon)
            }