java android svg android-glide

java - ¿Glide tiene un método para cargar PNG y SVG?



android android-glide (2)

Estoy usando Glide para cargar algunas imágenes de forma asíncrona en algunos de mis ImageView s, y sé que puede manejar imágenes como PNG o JPG ya que puede manejar SVG .

La cosa es que, hasta donde yo sé, la forma en que cargo esos dos tipos de imagen es diferente. Me gusta:

Cargando imágenes "normales"

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

Cargando 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);

Y si trato de cargar SVG con el primer método, no funcionará. Si intento cargar PNG o JPG con el segundo método, tampoco funcionará.

¿Hay alguna forma genérica de cargar ambos tipos de imágenes con Glide?

El servidor del que estoy obteniendo esas imágenes no me dice el tipo de imagen antes de descargarla. Es un servidor REST y el recurso se recuperará de forma similar a "http://foo.bar/resource" . La única forma de saber el tipo de imagen es leer la respuesta HEAD.


Agregué una tubería de decodificación flexible para decodificar una imagen o SVG, ¡tal vez pueda ayudar! basado en el ejemplo de deslizamiento SVG

Descifrador

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

Transcodificador

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 }

Recurso Decodificado

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

Módulo de deslizamiento

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 }

}


Puede usar Glide y AndroidSVG juntos para lograr su objetivo.

Hay una muestra de Glide para SVG. Ejemplo de muestra

Configurar 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 con 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 esta manera puedes lograr tu objetivo. Espero que esto sea útil.