Ich benutze Glide um einige Bilder asynchron in einige meiner ImageView
s zu laden, und ich weiß, dass es Bilder wie PNG
oder JPG
behandeln kann, wie es SVG
verarbeiten kann.
Die Sache ist, soweit ich weiß, unterscheidet sich die Art und Weise, wie ich diese beiden Bildarten lade. Mögen:
Laden "normaler" Bilder
Glide.with(mContext)
.load("URL")
.into(cardHolder.iv_card);
Laden von 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);
Und wenn ich versuche, SVG mit der ersten Methode zu laden, funktioniert es nicht. Wenn ich versuche, PNG oder JPG mit der zweiten Methode zu laden, funktioniert es auch nicht.
Gibt es eine generische Möglichkeit, beide Bildtypen mit Glide zu laden?
Der Server, von dem ich diese Bilder abrufe, sagt mir nicht, welchen Bildtyp ich vor dem Herunterladen habe. Es ist ein REST -Server, und die Ressource wird auf eine Weise abgerufen wie "http://foo.bar/resource"
. Die einzige Möglichkeit, den Bildtyp zu kennen, ist das Lesen der Antwort HEAD.
Sie können Glide & AndroidSVG zusammen verwenden, um Ihr Ziel zu erreichen.
Es gibt ein Beispiel von Glide for SVG. Beispielbeispiel
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>());
Verwenden Sie RequestBuilder mit 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);
Auf diese Weise können Sie Ihr Ziel erreichen. Ich hoffe das ist hilfreich.
Ich habe eine flexible Dekodierungspipeline hinzugefügt, um ein Bild oder SVG zu dekodieren. Vielleicht kann es helfen! basierend auf glide SVG Beispiel
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
}
Dekodierte Ressource
data class SvgOrImageDecodedResource(
val svg:SVG? = null,
val bitmap: Bitmap? = null)
Gleitmodul
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
}
}