'Show svg or image from network depending on type flutter

Hi I'm using a service that send me images, sometimes png or jpeg images and I use the flutter widget Image. In the other hand sometimes send me svg images intuit case I can use flutter_svg package, but I don't know how to switch between that widgets depending on the image type.

There isn't nothing on the url that I can use to determine the image type.

How I can do that?

UPDATE: Example response from the server, the image is on property lexeme_image

{
  "has_tts": true,
  "word": "one",
  "language_information": {},
  "from_language_name": "Spanish",
  "tts": "https://d1vq87e9lcf771.cloudfront.net/joeyn/b53723d682be1114be1cefce3ddbb908",
  "infinitive": null,
  "learning_language": "en",
  "translations": "un, una, uno",
  "learning_language_name": "English",
  "pos": "Numeral",
  "lexeme_image": "https://d2pur3iezf4d1j.cloudfront.net/images/4be10d03a4c6ac4078b6be0df2eb5247",
  "from_language": "es",
  "is_generic": false,
  "lexeme_id": "dd0309fb9cf34f8a2b2e029889c26ec5",
  "related_lexemes": [],
  "canonical_path": "/dictionary/English/one/d3a447831e3322e78309fa3a161c0ebf"
}


Solution 1:[1]

Rather than using the .network constructors provided by the Image widgets, retrieve the Image file with a network request like below:

HttpClient().getUrl(Uri.parse(STRING URL HERE))
    .then((HttpClientRequest request) => request.close())
    .then((HttpClientResponse response) => 
        response.pipe(File('foo').openWrite()));

or a better example using await:

HttpClientRequest request = await HttpClient().getUrl(Uri.parse(STRING URL HERE));
HttpClientResponse response = await request.close();

File file = File('foo');
await response.pipe(file .openWrite());

Then using the image library's PngDecoder and JpegDecoder decoder classes isValidFile method, you can check if the image is a png or jpeg. Example:

PngDecoder png = PngDecoder();
JpegDecoder jpg = JpegDecoder();

if(png.isValidFile(file) || jpg.isValidFile(file)) {
  //use `Image.file(file)`
}
else {
  //use `SvgPicture.file(file)`
}

If it is either of those, you can pass the file you retrieved to the Image.file constructor. If it's not then use the SvgPicture.file constructor.

Solution 2:[2]

I had this problem as well and wrote a little wrapper around svgpicture and the other image widgets: https://pub.dev/packages/hybrid_image

Solution 3:[3]

I found a pretty neat work-around for this and this is working fine for me.Hope that it helps you guys as well.

First use the flutter_svg package

Now i am assuming that you're getting the image extension as .svg or other image extensions like .jpg , .jpg etc.

Now i would recommend you to use Image.network and pass the SvgPicture widget in the errorBuilder property of Image.network

Here's an example for the same.

return Image.network(
    cryptoCoins[index]['logo_url'], //extensions like .jpg, .png etc
    height: 90,
    errorBuilder: (context, error, stackTrace) =>
    SvgPicture.network(
    cryptoCoins[index]['logo_url'], // for .svg extension
    height: 90,
       ),
     );

Hope it helps.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Christopher Moore
Solution 2 Stijn2210
Solution 3 Arijeet