What is the proper way to load images in Flutter and handle exceptions on load

Viewed 251

I'd like to know what is the proper way to load images from the device, and handle exceptions if the image is missing or corrupted. The user picking an image from the device and I want to open it. I'm using the image later in my code, so it is not enough for me just to show it in some widget. Currently, I'm using the following code that works fine in most cases:

  Future<ui.Image> imageLoadFromDevice(String path) async {

    await askPermissionForStorage();

    ImageProvider imageProvider = FileImage (  File ( path ), scale: 1 );

    Completer<ImageInfo> completer = Completer();
    imageProvider.resolve(ImageConfiguration()).addListener(ImageStreamListener((ImageInfo info, bool _) {
      completer.complete(info);
    }));

    ImageInfo imageInfo = await completer.future;

    return imageInfo.image;
  }

But if the image is missing or corrupted, there is a print in the console "Exception caught by image resource service", but my exception catcher above this function not getting the exception.

  1. Do I loading the image properly, or is there a better way?
  2. In case this code is OK, how should I catch exceptions, particularly missing file or corrupted image?
3 Answers

I'm not sure about corrupted images, but in the case of missing files, you can store the File(path) in a variable and use varname.exists() to check before setting your ImageProvider.

Good question! :)

You can use a simpler code below, that loading an image just as you want.

import 'dart:ui' as ui;

  Future<ui.Image> imageLoadFromDevice(String path) async {

    await askPermissionForStorage();

    File fileImage = File(path);
    final Uint8List imageUint8List =  await fileImage.readAsBytes();
    final ui.Codec codec = await ui.instantiateImageCodec(imageUint8List);
    final ui.FrameInfo frameInfo = await codec.getNextFrame();

    return frameInfo.image;
  }

To catch exceptions from this code you can put it inside try-catch. Any exception while loading the image, should produce a general exception that can be caught and handled.

To handle errors from an ImageStream, use the onError argument to the ImageStreamListener constructor:

imageProvider.resolve(ImageConfiguration()).addListener(ImageStreamListener(
  (ImageInfo info, bool _) { }, // called for success
  onError: (Object error, StackTrace? stackTrace) { }, // called for error
));
Related