36

I want to load a svg file from the web and show this file in an ImageView. For non vector images I use the Picasso library.

Is it possible to use this library for svg files as well?
Is there any way to load svg files from the web and show it in an ImageView?
I use the svg-android library to show svg files but i don't know how to get svg images from the web all the examples for this library use local files.

Janusz
  • 187,060
  • 113
  • 301
  • 369
mahdi
  • 16,257
  • 15
  • 52
  • 73
  • 1
    " is ther any way to load svg file from web and show it on image view ?" -- use `HttpUrlConnection`, HttpClient, OkHttp, Volley, Ion, or any number of other HTTP client libraries. – CommonsWare Jan 29 '15 at 13:36

8 Answers8

46

Update: For newer version please checkout the Glide Samples (https://github.com/bumptech/glide/tree/master/samples/svg)

-

You can use Glide (https://github.com/bumptech/glide/tree/v3.6.0) and AndroidSVG (https://bitbucket.org/paullebeau/androidsvg).

There is also a sample from Glide: https://github.com/bumptech/glide/tree/v3.6.0/samples/svg/src/main/java/com/bumptech/svgsample/app

Setup GenericRequestBuilder

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 uri = Uri.parse("https://de.wikipedia.org/wiki/Scalable_Vector_Graphics#/media/File:SVG_logo.svg");
            requestBuilder
                    .diskCacheStrategy(DiskCacheStrategy.SOURCE)
                            // SVG cannot be serialized so it's not worth to cache it
                    .load(uri)
                    .into(mImageView);
Rags93
  • 1,424
  • 1
  • 14
  • 14
  • 5
    You sir, saved my day :D – Mauker Nov 22 '15 at 03:43
  • 2
    what is requestBuilder? what is SvgDrawableTranscoder? what is SvgDecoder? what is SvgDecoder? what is SvgSoftwareLayerSetter? – Subkhan Sarif Nov 29 '15 at 18:23
  • 1
    Please look at the sample from Glide: https://github.com/bumptech/glide/tree/v3.6.0/samples/svg/src/main/java/com/bumptech/svgsample/app Requestbuilder is a "GenericRequestBuilder" from Glide (http://bumptech.github.io/glide/javadocs/latest/index.html) SVGDrawableTranscoder, SVGDecoder and SVGSoftwareLayerSetter are Classes to extend Glide to load and display SVGs with the help of AndroidSVG. – Rags93 Nov 30 '15 at 12:21
  • 1
    good example from glide 3.6.0, but I didn't know how to do it on 4.0.0. btw if you could downgrade to 3.6.0 ( like I did on my project ) its works perfectly! – jfcogato Jun 09 '17 at 14:37
  • 1
    where to get SvgDrawableTranscode(), SvgDecoder().. please if you can post the link. – Aman Verma Sep 24 '17 at 11:49
  • 1
    Both class can be found in the "sample from Glide" in the answer. https://github.com/bumptech/glide/tree/v3.6.0/samples/svg/src/main/java/com/bumptech/svgsample/app – Rags93 Sep 25 '17 at 12:59
  • 1
    Many thanks! But I had to downgrade my Glide version. Please update your solution to the latest version of Glide (4.3.1). – shahrukhamd Nov 09 '17 at 09:51
  • @Rags93 The code is not saving image for offline for me. Anything else needed to manage offline saving – Aditi Dec 12 '17 at 10:48
  • Maybe this on from the Glide Issues can help you: https://github.com/bumptech/glide/issues/1239 – Rags93 Dec 12 '17 at 13:30
  • 3
    I'm using glide 4.9.0, there are a lot of changes. to you have any up to date example? – Nininea Jun 18 '19 at 09:11
13

Please refer to Having issue on Real Device using vector image in android. SVG-android

In the users post he asks a similar question and suggest he uses:

Create a member variable for the ImageView in your layout file;

private ImageView mImageView;

// intialize in onCreate(Bundle savedInstanceState)
mImageView = (ImageView) findViewById(R.id.image_view);

Download the image

private class HttpImageRequestTask extends AsyncTask<Void, Void, Drawable> {
    @Override
    protected Drawable doInBackground(Void... params) {
        try {


            final URL url = new URL("http://upload.wikimedia.org/wikipedia/commons/e/e8/Svg_example3.svg");
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
            InputStream inputStream = urlConnection.getInputStream();
            SVG svg = SVGParser. getSVGFromInputStream(inputStream);
            Drawable drawable = svg.createPictureDrawable();
            return drawable;
        } catch (Exception e) {
            Log.e("MainActivity", e.getMessage(), e);
        }

        return null;
    }

    @Override
    protected void onPostExecute(Drawable drawable) {
        // Update the view
        updateImageView(drawable);
    }
}

Then Apply the drawable to the Imageview

@SuppressLint("NewApi")
private void updateImageView(Drawable drawable){
    if(drawable != null){

        // Try using your library and adding this layer type before switching your SVG parsing
        mImageView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
        mImageView.setImageDrawable(drawable);
    }
}

SVGParser is available at https://github.com/pents90/svg-android

Community
  • 1
  • 1
kandroidj
  • 13,784
  • 5
  • 64
  • 76
  • it`s returm me this error : com.larvalabs.svgandroid.SVGParseException: org.xml.sax.SAXException: No input specified. for this line : SVG svg = SVGParser.getSVGFromInputStream(inputStream); – mahdi Jan 29 '15 at 13:57
  • 1
    Yes. this method expects XML returned, and i was using a .svg file. So i am going to update my answer with a valid XML source. Sorry for the delay – kandroidj Jan 29 '15 at 14:01
  • 1
    @mahdi Please see updated answer which can actually refer to .svg or .xml files. this is because .svg really contains xml – kandroidj Jan 29 '15 at 14:07
  • getting error org.apache.harmony.xml.ExpatParser$ParseException: At line 1, column 0: no element found in this line SVG svg = SVGParser.getSVGFromInputStream(inputStream); – Binil Jul 20 '17 at 10:24
  • how to load .svg or .xml file using Picasso android...onBitmapfailed() called everytime – Aman Verma Sep 23 '17 at 20:30
  • 1
    @AshishPatel see https://code.google.com/archive/p/svg-android/ it is in OP's questions since it is the library he is using – kandroidj Nov 28 '17 at 14:26
11

Use this Glide based library loading xml

Add dependency

  compile 'com.github.ar-android:AndroidSvgLoader:1.0.0'

for latest android dependency Gradle use this instead

implementation 'com.github.ar-android:AndroidSvgLoader:1.0.0'

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <ImageView
        android:id="@+id/ivimage"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

MainActivity.java

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.list_item);            

        ImageView image = (ImageView) findViewById(R.id.ivimage);

        SvgLoader.pluck()
                .with(this)
                .setPlaceHolder(R.mipmap.ic_launcher, R.mipmap.ic_launcher)
                .load("http://www.clker.com/cliparts/u/Z/2/b/a/6/android-toy-h.svg", image);

    }

    @Override protected void onDestroy() {
        super.onDestroy();
        SvgLoader.pluck().close();
    }
}
Michael
  • 588
  • 11
  • 19
Ramesh sambu
  • 3,577
  • 2
  • 24
  • 39
  • Glide has a pretty annoying license (one of the more confusing ones I've seen in a while) Would be nice to have a solution that does not require I present license docs in my app. – StarWind0 Feb 22 '18 at 05:28
  • Also include this inside project build.gradle file: allprojects { repositories { maven { url 'https://jitpack.io' } } } – Farmaker Oct 25 '18 at 16:01
  • this library gives me this error : Program type already present: com.caverock.androidsvg.CSSParser$Attrib – Ahmed Adel Ismail Jun 19 '19 at 00:11
7

Kotlin and Coil Library to load SVG from URL:

  1. Add Kotlin image loading library to build.gradle (Module: app) (It also supports other images):

Gradle:

implementation 'io.coil-kt:coil:1.4.0'
implementation 'io.coil-kt:coil-svg:1.4.0'

or

Kts:

implementation("io.coil-kt:coil:1.4.0")
implementation("io.coil-kt:coil-svg:1.4.0")
  1. Add below extension function to any Kotlin file of your project, (outside of a class not inside of a class):

Here I used AppCompatImageView in xml, if you use only ImageView replace AppCompatImageView by ImageView from below function.

fun AppCompatImageView.loadSvgOrOther(myUrl: String?, cache: Boolean = true, errorImg: Int = R.drawable.logo_round // Place any error image from your drawable) {

myUrl?.let {
    if (it.lowercase().endsWith("svg")) {
        val imageLoader = ImageLoader.Builder(this.context)
            .componentRegistry {
                add(SvgDecoder(this@loadSvgOrOther.context))
            }.build()

        val request = ImageRequest.Builder(this.context).apply {
            error(errorImg)
            placeholder(errorImg)
            data(it).decoder(SvgDecoder(this@loadSvgOrOther.context))
        }.target(this).build()

        imageLoader.enqueue(request)
    } else {
        val imageLoader = ImageLoader(context)

        val request = ImageRequest.Builder(context).apply {
            if (cache) {
                memoryCachePolicy(CachePolicy.ENABLED)
            } else {
                memoryCachePolicy(CachePolicy.DISABLED)
            }
            error(errorImg)
            placeholder(errorImg)
            data("$it")
        }.target(this).build()

        imageLoader.enqueue(request)
    }
  }
} // loadSvgOrOther
  1. Now use like below:

    myAppCompatImageView.loadSvgOrOther("https[:]//example[.]com/image.svg")
    

Hope this will help, who wants to use Kotlin to load svg, png, jpg etc Images.

Touhid
  • 1,556
  • 18
  • 18
  • in my case SvgDecoder class not find. Can you help me the process of calling it – Aminul Haque Aome Aug 25 '20 at 17:57
  • 1
    @AminulHaqueAome Also add this line in gradle: implementation("io.coil-kt:coil-svg:0.11.0") (Answer updated) – Touhid Aug 26 '20 at 13:57
  • yeah I also tried that. But the problem was, it was conflicting between the version of coil and coile svg. May be I can solve the issue today. And Thanks for your reply vai – Aminul Haque Aome Aug 27 '20 at 04:19
  • vai, another question. How can I use placeHolder in this method? – Aminul Haque Aome Sep 13 '20 at 09:57
  • For placeholder or other options you can see the official documentation here: https://github.com/coil-kt/coil – Touhid Oct 05 '20 at 06:02
  • 1
    @Touhid imageLoader.execute(request) got error and say function must be suspend. why?? . and why LoadRequest is unknown?? – Sadegh J Apr 24 '21 at 10:35
  • @Sadegh Try to use mentioned version (0.11.0) of coil. if you use the latest version then please go throw their official documentation. https://github.com/coil-kt/coil – Touhid Apr 24 '21 at 14:51
  • @RuchaBhattJoshi check this https://stackoverflow.com/questions/35507893/does-glide-have-a-method-for-loading-both-png-and-svg/67242151#67242151 – Sadegh J Aug 18 '21 at 18:56
4

Hope the below code is useful for you.

  1. Add this dependency in build.gradle

    implementation 'com.github.corouteam:GlideToVectorYou:v2.0.0'

  2. Now start working in MainActivity.java

    ImageView image = (ImageView) findViewById(R.id.ivimage);

    String url= https://your_url/banking.svg GlideToVectorYou.init().with(this).load(Uri.parse(url),image);

  • 1
    this is great, thanks! just note - that also in project level gradle file, need to add: `maven { url 'https://jitpack.io' }` , under `repositories` – Rus_o Feb 01 '22 at 12:38
2

You can use this library

https://github.com/2coffees1team/GlideToVectorYou

As he say : "The library is based on Glide and offers the same functionalities + svg support".

Ali Hasan
  • 653
  • 9
  • 8
0

Load SVG using Glide V4 or above

Add dependencies in app.gradle > dependencies

implementation 'com.github.qoqa:glide-svg:2.0.4'
implementation 'com.github.bumptech.glide:glide:4.11.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'

Make new class SampleAppGlideModule.java and go to Build>Make Project(ctrl+f9)

import android.content.Context;
import android.util.Log;

import androidx.annotation.NonNull;

import com.bumptech.glide.GlideBuilder;
import com.bumptech.glide.annotation.GlideModule;
import com.bumptech.glide.module.AppGlideModule;

@GlideModule
public class SampleAppGlideModule extends AppGlideModule {



    @Override
    public boolean isManifestParsingEnabled() {
        return super.isManifestParsingEnabled();
    }

    @Override
    public void applyOptions(@NonNull Context context, @NonNull GlideBuilder builder) {
        super.applyOptions(context, builder);
        builder.setLogLevel(Log.DEBUG);
    }
}

Load SVG using Glide V4 or above

GlideApp.with(this)                      
.load(contentLangModels.get(i).getContentImage()).into(contentLangBinding.ivExtra);
Manthan Patel
  • 1,784
  • 19
  • 23
0

You can use Coil Image loading library,

Add the following dependencies to your app level build.gradle file,

def coilVersion = '1.2.2'
implementation "io.coil-kt:coil:$coilVersion"
implementation "io.coil-kt:coil-svg:$coilVersion"

Now create this method,

fun ImageView.loadImageFromUrl(imageUrl: String) {
val imageLoader = ImageLoader.Builder(this.context)
    .componentRegistry { add(SvgDecoder(this@loadImageFromUrl.context)) 
}
    .build()

val imageRequest = ImageRequest.Builder(this.context)
    .crossfade(true)
    .crossfade(300)
    .data(imageUrl)
    .target(
        onStart = {
            //set up an image loader or whatever you need
        },
        onSuccess = { result ->
            val bitmap = (result as BitmapDrawable).bitmap
            this.setImageBitmap(bitmap)
            //dismiss the loader if any
        },
        onError = {
            /**
             * TODO: set an error drawable
             */
        }
    )
    .build()

imageLoader.enqueue(imageRequest)

}

Now you can call this extension function from your ImageView,

imgView.loadImage(imageUrl)

This will work for svgs, pngs. I have not tried it with jpgs, but should work with them as well.

Anubhav
  • 1,984
  • 22
  • 17