In the app I’m using the following sample to load an SVG image into ImageView:
Glide.with(context) .using(Glide.buildStreamModelLoader(Uri.class, context), 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()) .diskCacheStrategy(DiskCacheStrategy.NONE) .load(uri) .into(imageView);
An ImageView in xml looks like this:
<ImageView android:layout_width="46dp" android:layout_height="46dp" android:layout_marginTop="25dp" android:layout_gravity="center" />
So, the problem can be seen on the image below. The right icon was set from app’s resources, while the left one is loaded from server using Glide. For some reason image is not scaling properly and looks blurry.
I’ve already tried the solution from this answer: Image size too small when loading SVG with Glide, but it doesn’t work.
Advertisement
Answer
After upgrading to glide v4 the problem has gone. Now I’m using the following code for loading svg:
GlideApp.with(context) .as(PictureDrawable.class) .transition(withCrossFade()) .fitCenter() .listener(new SvgSoftwareLayerSetter()) .apply(RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.RESOURCE)) .load(uri).into(imageView);
And in my AppGlideModule I have:
@Override public void registerComponents(@NonNull Context context, @NonNull Glide glide, Registry registry) { registry.register(SVG.class, PictureDrawable.class, new SvgDrawableTranscoder()) .prepend(SVG.class, new SvgEncoder()) .append(InputStream.class, SVG.class, new SvgDecoder()); }
SvgDrawableTranscoder converts SVG to PictureDrawable with one simple method:
public class SvgDrawableTranscoder implements ResourceTranscoder<SVG, PictureDrawable> { @Override public Resource<PictureDrawable> transcode(@NonNull Resource<SVG> toTranscode, @NonNull Options options) { SVG svg = toTranscode.get(); Picture picture = svg.renderToPicture(); PictureDrawable drawable = new PictureDrawable(picture); return new SimpleResource<>(drawable); } }
And that’s how I implemented SvgEncoder class:
public class SvgEncoder implements ResourceEncoder<SVG>{ @NonNull @Override public EncodeStrategy getEncodeStrategy(@NonNull Options options) { return EncodeStrategy.SOURCE; } @Override public boolean encode(@NonNull Resource<SVG> data, @NonNull File file, @NonNull Options options) { try { SVG svg = data.get(); Picture picture = svg.renderToPicture(); picture.writeToStream(new FileOutputStream(file)); return true; } catch (Exception e) { e.printStackTrace(); return false; } } }