androidflutterimageencodingnetworkimageview

Flutter: Failed to decode image - Failed to create image decoder with message 'invalid input'Input contained an error


I am trying to display an image from a URL inside a NetworkImage in a Flutter App but an error occur that prevents the image from being displayed, here is the logged exception:

D/HeifDecoderImpl(11496): No valid image or sequence available
E/FlutterJNI(11496): Failed to decode image
E/FlutterJNI(11496): android.graphics.ImageDecoder$DecodeException: Failed to create image decoder with message 'invalid input'Input contained an error.
E/FlutterJNI(11496):    at android.graphics.ImageDecoder.nCreate(Native Method)
E/FlutterJNI(11496):    at android.graphics.ImageDecoder.access$200(ImageDecoder.java:173)
E/FlutterJNI(11496):    at android.graphics.ImageDecoder$ByteBufferSource.createImageDecoder(ImageDecoder.java:250)
E/FlutterJNI(11496):    at android.graphics.ImageDecoder.decodeBitmapImpl(ImageDecoder.java:1862)
E/FlutterJNI(11496):    at android.graphics.ImageDecoder.decodeBitmap(ImageDecoder.java:1855)
E/FlutterJNI(11496):    at io.flutter.embedding.engine.FlutterJNI.decodeImage(FlutterJNI.java:559)

════════ Exception caught by image resource service ════════════════════════════
The following _Exception was thrown resolving an image codec:
Exception: Invalid image data

When the exception was thrown, this was the stack:
#0      _futurize (dart:ui/painting.dart:6966:5)
painting.dart:6966
#1      ImageDescriptor.encoded (dart:ui/painting.dart:6775:12)
painting.dart:6775
#2      instantiateImageCodecWithSize (dart:ui/painting.dart:2287:60)
painting.dart:2287
#3      PaintingBinding.instantiateImageCodecWithSize (package:flutter/src/painting/binding.dart:141:15)
binding.dart:141
#4      NetworkImage._loadAsync (package:flutter/src/painting/_network_image_io.dart:131:20)
_network_image_io.dart:131
<asynchronous suspension>
#5      MultiFrameImageStreamCompleter._handleCodecReady (package:flutter/src/painting/image_stream.dart:985:3)
image_stream.dart:985
<asynchronous suspension>

Image provider: NetworkImage("https://mega-store.s3.eu-west-2.amazonaws.com/shelly/0.2782753988222566.png", scale: 1.0)
Image key: NetworkImage("https://mega-store.s3.eu-west-2.amazonaws.com/shelly/0.2782753988222566.png", scale: 1.0)
════════════════════════════════════════════════════════════════════════════════

Here is the URL of the image: https://mega-store.s3.eu-west-2.amazonaws.com/shelly/0.2782753988222566.png

The error only occurs in Android 11 Devices according to my testing, I have tested the same image with the same code in Android 12 and IOS 17.4 and everything works perfectly.


Solution

  • The issue is that the image in the URL is saved in .png file extension but it is Encoding is actually AV1 Image File Format (AVIF), and this is obvious when you download the image from the URL and check the file encoding from the file info:

    enter image description here

    The reason that the image is not working in Android 11 Devices is that the AV1 File Format is supported in Android only starting from Android 12, here is a snippet about that from the official Android Docs:

    AVIF

    Android 12 (API level 31) and higher support images that use the AV1 Image File Format (AVIF). AVIF is a container format for images and sequences of images encoded using AV1. AVIF takes advantage of the intra-frame encoded content from video compression. This dramatically improves image quality for the same file size when compared to older image formats, such as JPEG. For an in-depth look at the advantages of this format, see Jake Archibald's blog post.

    Hence, if you continued testing in Android versions below Android 11 it will also not work.

    ✅ Suggested Solutions:

    1. You can convert the images to another familiar format such as PNG or JPEG which has no issues in all Android and IOS versions.
    2. You can use the flutter_avif package to display the AV1 images, but you will have to check the file type first to know if it is actually AV1 to use the widget provided by the package or not, because you may have other images with other file formats.