Flutter Exception Won't Catch Invalid Image Data - flutter

I have a synchronous method that reads an image from disk. I'm trying to handle all scenarios where the image didn't get saved properly and is corrupted.
If I place a fake.jpg in my app's documents folder and then run the below code on it, it crashes with: Invalid image data. So the Image.file portion of my code isn't catching an underlying exception.
Widget getPhotoFile(String path) {
final file = File(path);
try {
if (!file.existsSync()) throw Exception('Photo Not Available');
final photo = Image.file(
key: UniqueKey(),
file,
fit: BoxFit.cover,
);
return photo;
} catch (error) {
return Text('No Image');
}
}
Why won't my catch block work for the Image exception and return the Text widget instead?

Related

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

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.
Do I loading the image properly, or is there a better way?
In case this code is OK, how should I catch exceptions, particularly missing file or corrupted image?
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
));

How to reload a network image in flutter?

When using a network image in flutter sometimes I got the error Connection closed before full header was received. The code below allows me to output the error but how can I force the widget to reload the image?
Image.network(p.thumbURL,
errorBuilder: (BuildContext context, Object exception, StackTrace stackTrace) {
Log.e(exception);
return Container();
},
),
give a value key to your image widget, otherwise it won't rebuild when you update your link
key: ValueKey(url),
update your url by adding a new meaningless query string at the end, e.g. adding a time
setState(() {
url = url.split('?r')[0] + '?r=' + DateTime.now().millisecondsSinceEpoch.toString();
});

Flutter check if Asset image exists

Is it possible to conditionally load an asset image, only if it exists? Therefore you could load a default image if it does not exist in the Assets bundle.
One way you can check if the asset image exists is by trying to display it. If it throws an Exception, display a different widget instead.
Future<Widget> getAssetImage(String path) async {
try {
await rootBundle.load(path);
return Image.asset(path);
} catch (_) {
return SizedBox(); // Return this widget
}
}
Otherwise, you can check the AssetManifest.json and cross-check the asset to be used with the list before trying to access it.

Flutter : fetch image from picture Directory

I'm working with saved image from Url with Gallery Saver. Everything it's oke , i can insert image from URL, but i don't know how to fetch image from picture Directory .
It's different about getApplicationDocumentsDirectory() or getExternalStorageDirectory() ?
I want to display the image that was just saved.
Any solution ?
Save image Code :
void _testSaveImage() async {
String path = "${Urls.BASE_API_IMAGE}/berita/${widget.gambarBerita}";
GallerySaver.saveImage(path).then((bool success) {
print('Success add image $path');
}).catchError((onError) {
print('Error add image $path');
});
}
Location Image saved
Then just return the path you have and use a Image.file() widget to display it, lets say you have a Column():
Column(children: <Widget>[
[...]
Text('Here is my image:'),
if (path.isNotEmpty && path != null)
SizedBox(
height: 200,
width: 200,
child: Image.file(File(path),
),
Text('Caption of the image'),
[...]
),
Docs for Image class here
Load local saved images using path and use it
var file = new File('path');
Image.file(file )

Evict image from cache flutter not working

I'm trying to remove a single image entry from the flutter cache using the evict() method from the NetworkImage class and it keeps failing.
Here how I do the evict:
final NetworkImage provider = NetworkImage(url);
try {
bool res = await provider.evict();
print("eviction result : $res");
} catch (error) {
print(error.toString());
}
And how my image is rendered:
CircleAvatar(
radius: 80,
backgroundImage: NetworkImage(url))),
This print flutter: eviction result : false in the console and the image cache is not removed. Any idea of what i'm missing ?