#flutter
#flutter
Вопрос:
Я хотел бы знать, как правильно загружать изображения с устройства и обрабатывать исключения, если изображение отсутствует или повреждено. Пользователь выбирает изображение с устройства, и я хочу его открыть. Я использую изображение позже в своем коде, поэтому мне недостаточно просто показать его в каком-нибудь виджете. В настоящее время я использую следующий код, который в большинстве случаев работает нормально:
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;
}
Но если изображение отсутствует или повреждено, в консоли отображается сообщение «Исключение, перехваченное службой ресурсов изображений», но мой перехватчик исключений над этой функцией не получает исключения.
- Правильно ли я загружаю изображение или есть лучший способ?
- В случае, если этот код в порядке, как мне перехватывать исключения, в частности, отсутствующий файл или поврежденное изображение?
Ответ №1:
Я не уверен насчет поврежденных изображений, но в случае отсутствия файлов вы можете сохранить File(path)
их в переменной и использовать varname.exists()
для проверки перед настройкой вашего ImageProvider.
Комментарии:
1. Спасибо, я знаком с File(path).exists() . В этом случае это определенно возможно. Но в случаях race / edge все еще существует вероятность того, что «exists» вернет true, тогда файл будет чем-то удален, и я бы попытался открыть отсутствующий файл. Поэтому мне нужно получить исключение в этом случае. Но этот код просто выводится в консоль: «Исключение, обнаруженное службой ресурсов изображений. Не удается открыть file, path = …», но исключения нет, поэтому я не могу его поймать.
Ответ №2:
Хороший вопрос! 🙂
Вы можете использовать более простой код ниже, который загружает изображение так, как вы хотите.
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;
}
Чтобы перехватить исключения из этого кода, вы можете поместить его в try-catch. Любое исключение при загрузке изображения должно создавать общее исключение, которое можно перехватить и обработать.
Ответ №3:
Для обработки ошибок из an ImageStream
используйте onError
аргумент ImageStreamListener
конструктора:
imageProvider.resolve(ImageConfiguration()).addListener(ImageStreamListener(
(ImageInfo info, bool _) { }, // called for success
onError: (Object error, StackTrace? stackTrace) { }, // called for error
));