Repository navigation
Description
Steps to reproduce
- Use
image_pickeron Android and pick a large photo (e.g. a 12 MP, 4000x3000 camera image) with a size limit, e.g.ImagePicker().pickImage(source: ImageSource.gallery, maxWidth: 1280, maxHeight: 1280). - Look at how
ImageResizer.resizeImageIfNeededdecodes the image (packageimage_picker_android, fileandroid/src/main/java/io/flutter/plugins/imagepicker/ImageResizer.java; checked against the latest release, 0.8.13+23).
Expected results
calculateSampleSize picks a power-of-two inSampleSize from the original image size, so the 4000x3000 photo is decoded at 2000x1500 (about 12 MB as ARGB_8888) before createScaledBitmap scales it to 1280x960. This is what flutter/packages#3423 ("Improved Bitmap resize on Android", for #118383) set out to do.
Actual results
inSampleSize is always 1, so the photo is always decoded at full resolution (4000x3000, about 48 MB) before being scaled.
In resizeImageIfNeeded, a fresh BitmapFactory.Options is created and passed straight to calculateSampleSize:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize =
calculateSampleSize(options, (int) targetSize.getWidth(), (int) targetSize.getHeight());
Bitmap bmp = decodeFile(imagePath, options);calculateSampleSize reads options.outWidth / options.outHeight, but this options object has never been used for a decode, so those fields still hold their defaults. The condition height > targetHeight || width > targetWidth is therefore never true and the method returns 1. The original dimensions were already read by readFileDimensions(), but into a different Options instance, and only the resulting SizeFCompat is kept.
A side effect is that passing maxWidth / maxHeight makes memory use worse than not passing them: without them the plugin returns the original file untouched, with them it always does a full-resolution decode plus a re-encode. Google Play Console's Android vitals flags this pattern as "Use bitmap downsampling to improve app performance".
A possible fix is to compute the sample size from originalSize (the SizeFCompat returned by readFileDimensions) instead of from the undecoded options.
Code sample
Code sample
final image = await ImagePicker().pickImage(
source: ImageSource.gallery,
maxWidth: 1280,
maxHeight: 1280,
);Screenshots or Video
N/A
Logs
N/A. The behavior follows directly from the code above; we confirmed it by reproducing calculateTargetSize + calculateSampleSize for 4000x3000, 4032x3024, 4080x3072 and 8160x6120 sources, all of which end up with inSampleSize = 1.
Flutter Doctor output
Doctor output
Flutter 3.47.4 (stable), macOS, Android emulator API 37.
image_picker_android 0.8.13+19 in the app; code inspected in 0.8.13+23 (latest).
Activity
mbcorona commentedon Sep 21, 2026
Hi @FatJohn , thanks for the report. Routing to the Android team to check on computing the sample size from originalSize.
jesswrd commentedon Sep 22, 2026
@mbcorona Can you check if this is a regression? It looks like the reporter used 3.47.4 (stable), Android emulator API 37, image_picker_android 0.8.13+19.
anilcancakir commentedon Sep 27, 2026
I've sent a fix in flutter/packages#13038.
calculateSampleSizenow uses the dimensionsreadFileDimensionsalready read, so a resize withmaxWidthormaxHeightsubsamples while decoding; the output size is unchanged. To answer the regression question: it is not one,inSampleSizehas been 1 since it was introduced in flutter/packages#3423.[image_picker] Subsample large images when resizing on Android (flutt…
github-actions commentedon Oct 16, 2026
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of
flutter doctor -vand a minimal reproduction of the issue.