[mob] Gracefully handle decompress image exception (#6811)

## Description
On Android 16 with flutter upgrade, we are seeing `Could not decompress
image.` error for heic images taken from Iphone 16.
Instead of showing broken image, rendering the compressed version of the
image on UI.

Also, increased the minWidth/minWidth from default 1920/1080 to 8000/800

Refer:
https://pub.dev/packages/flutter_image_compress#minwidth-and-minheight
> If your image width is smaller than minWidth or height smaller than
minHeight, scale will be 1, that is, the size will not change.

```
E/FlutterJNI( 7914): Failed to decode image
E/FlutterJNI( 7914): java.io.IOException: getPixels failed with error invalid input
E/FlutterJNI( 7914):     at android.graphics.ImageDecoder.nDecodeBitmap(Native Method)
E/FlutterJNI( 7914):     at android.graphics.ImageDecoder.decodeBitmapInternal(ImageDecoder.java:1676)
E/FlutterJNI( 7914):     at android.graphics.ImageDecoder.decodeBitmapImpl(ImageDecoder.java:1865)
E/FlutterJNI( 7914):     at android.graphics.ImageDecoder.decodeBitmap(ImageDecoder.java:1850)
E/FlutterJNI( 7914):     at io.flutter.embedding.engine.FlutterJNI.decodeImage(FlutterJNI.java:571)
```

## Tests

Tested locally on Simulator with sample image.
This commit is contained in:
Neeraj
2025-08-11 11:56:07 +05:30
committed by GitHub

View File

@@ -410,13 +410,18 @@ class _ZoomableImageState extends State<ZoomableImage> {
precacheImage(
imageProvider,
context,
onError: (exception, _) async {
_logger
.info(exception.toString() + ". Filename: ${_photo.displayName}");
onError: (exception, s) async {
if (exception.toString().contains(
"Codec failed to produce an image, possibly due to invalid image data",
)) {
unawaited(_loadInSupportedFormat(file));
"Codec failed to produce an image, possibly due to invalid image data",
) ||
exception.toString().contains(
"Could not decompress image.",
)) {
unawaited(_loadInSupportedFormat(file, e));
} else {
_logger.warning(
"Failed to load image ${_photo.displayName} with error: $exception",
);
}
},
).then((value) {
@@ -471,8 +476,13 @@ class _ZoomableImageState extends State<ZoomableImage> {
bool _isGIF() => _photo.displayName.toLowerCase().endsWith(".gif");
Future<void> _loadInSupportedFormat(File file) async {
_logger.info("Compressing ${_photo.displayName} to viewable format");
Future<void> _loadInSupportedFormat(
File file,
Object unsupportedErr,
) async {
_logger.info(
"Compressing ${_photo.displayName} to viewable format due to $unsupportedErr",
);
_convertToSupportedFormat = true;
Uint8List? compressedFile;
@@ -492,7 +502,11 @@ class _ZoomableImageState extends State<ZoomableImage> {
quality: 85,
);
} else {
compressedFile = await FlutterImageCompress.compressWithFile(file.path);
compressedFile = await FlutterImageCompress.compressWithFile(
file.path,
minHeight: 8000,
minWidth: 8000,
);
}
if (compressedFile != null) {