Download svg image to present in Android ImageView how?

0

I have a api link that returns me a json on Android. That json is binded to a class using Jackson. But I need to use the url that is contained in json which is a svg image. I want to use this image to display the image in my custom listview but I can not convert this svg to a valid image in any way.

I've tried several libraries like svg-android, androidsvg1.2, glide, tried samples, tried to convert svg to png using the svg2png library and nothing works, in desperation I still tried to use the Picasso squared library, but obviously I was not going to because the library does not support this svg image.

I've been in this for more than 8 hours so I've already tested almost everything that is unnecessarily spread over the internet ... thank you so much a little handsome!

    
asked by anonymous 19.12.2017 / 19:07

1 answer

1

The Glide , with some adjustments and with the help of AndroidSVG , it supports SVG loading. You have an example in their repository that shows how. I will reproduce the current code for later:

Add the appropriate dependencies (check versions):

compile 'com.github.bumptech.glide:glide:4.4.0'
compile 'com.github.bumptech.glide:annotations:4.4.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.4.0'
implementation 'com.caverock:androidsvg:1.2.1'

You need to create a ResourceDecoder to convert a InputStream to SVG .

/**
 * Decodes an SVG internal representation from an {@link InputStream}.
 */
public class SvgDecoder implements ResourceDecoder<InputStream, SVG> {

  @Override
  public boolean handles(@NonNull InputStream source, @NonNull Options options) {
    // TODO: Can we tell?
    return true;
  }

  public Resource<SVG> decode(@NonNull InputStream source, int width, int height,
      @NonNull Options options)
      throws IOException {
    try {
      SVG svg = SVG.getFromInputStream(source);
      return new SimpleResource<>(svg);
    } catch (SVGParseException ex) {
      throw new IOException("Cannot load SVG from stream", ex);
    }
  }
}

A ResourceTranscoder to convert from SVG to Picture :

/**
 * Convert the {@link SVG}'s internal representation to an Android-compatible one
 * ({@link Picture}).
 */
public class SvgDrawableTranscoder implements ResourceTranscoder<SVG, PictureDrawable> {
  @Override
  public Resource<PictureDrawable> transcode(Resource<SVG> toTranscode, Options options) {
    SVG svg = toTranscode.get();
    Picture picture = svg.renderToPicture();
    PictureDrawable drawable = new PictureDrawable(picture);
    return new SimpleResource<>(drawable);
  }
}

Create a new module:

/**
 * Module for the SVG sample app.
 */
@GlideModule
public class SvgModule extends AppGlideModule {
  @Override
  public void registerComponents(@NonNull Context context, @NonNull Glide glide,
      @NonNull Registry registry) {
    registry.register(SVG.class, PictureDrawable.class, new SvgDrawableTranscoder())
        .append(InputStream.class, SVG.class, new SvgDecoder());
  }

  // Disable manifest parsing to avoid adding similar modules twice.
  @Override
  public boolean isManifestParsingEnabled() {
    return false;
  }
}

And a request listener:

/**
 * Listener which updates the {@link ImageView} to be software rendered, because
 * {@link com.caverock.androidsvg.SVG SVG}/{@link android.graphics.Picture Picture} can't render on
 * a hardware backed {@link android.graphics.Canvas Canvas}.
 */
public class SvgSoftwareLayerSetter implements RequestListener<PictureDrawable> {

  @Override
  public boolean onLoadFailed(GlideException e, Object model, Target<PictureDrawable> target,
      boolean isFirstResource) {
    ImageView view = ((ImageViewTarget<?>) target).getView();
    view.setLayerType(ImageView.LAYER_TYPE_NONE, null);
    return false;
  }

  @Override
  public boolean onResourceReady(PictureDrawable resource, Object model,
      Target<PictureDrawable> target, DataSource dataSource, boolean isFirstResource) {
    ImageView view = ((ImageViewTarget<?>) target).getView();
    view.setLayerType(ImageView.LAYER_TYPE_SOFTWARE, null);
    return false;
  }
}

I was able to load the Brazilian flag using the address that comes from your JSON:

Uri uri = Uri.parse("https://restcountries.eu/data/bra.svg");

GlideApp.with(this)
    .as(PictureDrawable.class)
    .listener(new SvgSoftwareLayerSetter())
    .load(uri).into(imageViewNet);

    
19.12.2017 / 19:46