Есть ли у Glide метод для загрузки как PNG, так и SVG?
Я использую Glide для асинхронной загрузки некоторых изображений в некоторые из моих ImageView
файлов, и я знаю, что он может обрабатывать изображения, подобные PNG
или JPG
поскольку он может обрабатывать SVG
.
Дело в том, что, насколько я знаю, способ загрузки этих двух типов изображений отличается. Нравится:
Загрузка "обычных" изображений
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 .
Переведено автоматически
Ответ 1
Вы можете использовать Glide и AndroidSVG вместе для достижения своей цели.
Есть пример из Glide для SVG.Примерный пример
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>());
Используйте 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);
Таким образом вы сможете достичь своей цели. Надеюсь, это полезно.
Ответ 2
АЛЬТЕРНАТИВНЫЙ СПОСОБ: kotlin + Coil
Это решение будет хорошо работать с .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")
добавьте эту функцию в свой код:
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)
}
Затем вызовите этот метод в своем activity или фрагменте:
imageView.loadUrl(url)
// Sample SVG url : https://upload.wikimedia.org/wikipedia/commons/3/36/Red_jungle_fowl_white_background.png
Ответ 3
Я добавил гибкий конвейер декодирования для декодирования изображения или SVG, возможно, это поможет! на основе примера glide 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)
}
}
}
Перекодировщик
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
}
Декодированный ресурс
data class SvgOrImageDecodedResource(
val svg:SVG? = null,
val bitmap: Bitmap? = null)
Модуль Glide
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
}
}
Ответ 4
glidetovectoryу меня не сработал, поэтому я использовал coil с coil-svg extension library