Java Glide 有同时加载 PNG 和 SVG 的方法吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/35507893/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Does Glide have a method for loading both PNG and SVG?
提问by Mauker
I'm using Glideto load some images asynchronouslyinto some of my ImageView
s, and I know it can handle images like PNG
or JPG
as it can handle SVG
.
我使用滑翔到一些图像加载异步到一些我的ImageView
S,我知道它能够处理图像像PNG
或者JPG
因为它可以处理SVG
。
Thing is, As far as I know, the way I load those two kinds of image differs. Like:
事情是,据我所知,我加载这两种图像的方式不同。喜欢:
Loading "normal" images
加载“正常”图像
Glide.with(mContext)
.load("URL")
.into(cardHolder.iv_card);
Loading SVG
加载 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);
And if I try to load SVG with the first method it won't work. If I try to load PNG or JPG with the second method, it won't work either.
如果我尝试使用第一种方法加载 SVG,它将无法正常工作。如果我尝试使用第二种方法加载 PNG 或 JPG,它也不会工作。
Is there a generic way to load both image types using Glide?
是否有使用 Glide 加载两种图像类型的通用方法?
The server where I'm fetching those images from don't tell me the image type before I download it. It's a REST server and the resource will be retrieved in a way like "http://foo.bar/resource"
. The only way to know the image type is reading the HEAD response.
我从中获取这些图像的服务器在我下载之前不会告诉我图像类型。它是一个 REST 服务器,资源将以类似于"http://foo.bar/resource"
. 了解图像类型的唯一方法是读取 HEAD 响应。
采纳答案by Maheshwar Ligade
You can use Glide& AndroidSVGtogether to achieve your goal.
您可以结合使用Glide和AndroidSVG来实现您的目标。
There is sample from Glide for SVG.Sample Example
有来自 Glide for 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>());
Use RequestBuilder with uri
使用带有 uri 的 RequestBuilder
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);
This way you can achieve your goal. I hope this is helpful.
这样你就可以实现你的目标。我希望这是有帮助的。
回答by Josue Amador
I added a flexible decoding pipeline to decode an image or SVG, maybe can help! based on glide SVG example
我添加了一个灵活的解码管道来解码图像或 SVG,也许可以提供帮助!基于滑动 SVG 示例
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
}
}
}
回答by Justin
For others who reach this thread because they're looking for a way to load SVG's in Xamarin Android, the accepted answer won't work because a lot of those classes / methods don't seem to be available in the Xamarin Glide nuget package. Here is what worked for me:
对于其他人因为他们正在寻找一种在 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);
}
It requires the AndroidSVG.Xamarinnuget package.
它需要AndroidSVG.Xamarinnuget 包。