J'utilise Glide pour charger des images de manière asynchrone dans certains de mes ImageView
s, et je sais qu'il peut gérer des images telles que PNG
ou JPG
comme il peut gérer SVG
.
Pour autant que je sache, la façon dont je charge ces deux types d’images diffère. Comme:
Chargement d'images "normales"
Glide.with(mContext)
.load("URL")
.into(cardHolder.iv_card);
Chargement de 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);
Et si j'essaie de charger SVG avec la première méthode, cela ne fonctionnera pas. Si j'essaie de charger PNG ou JPG avec la deuxième méthode, cela ne fonctionnera pas non plus.
Existe-t-il un moyen générique de charger les deux types d'images à l'aide de Glide?
Le serveur sur lequel je vais chercher ces images ne me dit pas le type d’image avant de le télécharger. C'est un serveur REST et la ressource sera récupérée de la manière suivante: "http://foo.bar/resource"
. Le seul moyen de connaître le type d'image consiste à lire la réponse HEAD.
Vous pouvez utiliser Glide & AndroidSVG ensemble pour atteindre votre objectif.
Il y a un échantillon de Glide pour SVG. Sample Example
Configurer 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>());
Utiliser RequestBuilder avec 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);
De cette façon, vous pouvez atteindre votre objectif. J'espère que ceci est utile.
J'ai ajouté un pipeline de décodage flexible pour décoder une image ou un fichier SVG. basé sur glide SVG exemple
Décodeur
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)
}
}
}
Transcodeur
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
}
Ressource décodée
data class SvgOrImageDecodedResource(
val svg:SVG? = null,
val bitmap: Bitmap? = null)
Module de glisse
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
}
}