I want to load images in Android, but if the image is just too large I wanted to resize it prior to loading . I learned that one can use the BitmapFactory to get just the size of the image, then one can figure out an appropriate scaling factor and use BitmapFactory to load the image with the required dimensions (per the very competent suggestions I found in this related thread).
So I tried that and it refused to work. I spent the last hour picking through the code trying to figure out why such a simple operation wasn't having any effect whatsoever (the scaling factor was being utterly ignored!)
Then I stumbled upon Android issue 3072... turns out this has been identified as broken for GIF files for well over two years. I realize GIF isn't exactly modern but it's still out there and in wide use (my test set has a lot of them, which is why it seemed uniformly broken until I found that bug report).
My question is, what can I use as an alternative to BitmapFactory that will correctly read and resize a GIF file when a scaling factor is employed without silently ignoring it? Memory constraints preclude loading large images directly for further processing, so this would need to be a streaming solution.
My other question is, how many others run into old, unfixed bugs like this and either don't realize it or worse, rely on the API to accurately perform the requested function and end up with memory leaks and other strange surprises?
I ended up using the solution posted here.
options.inSampleSize = 2;
bitmap = BitmapFactory.decodeStream(new URL(url).openStream(),null, options);
Bitmap scaledBitmap = scaleDown(bitmap, 1280, true);
bitmap = scaledBitmap;
Where scaleDown
is:
public static Bitmap scaleDown(Bitmap realImage, float maxImageSize,
boolean filter) {
float ratio = Math.min(
(float) maxImageSize / realImage.getWidth(),
(float) maxImageSize / realImage.getHeight());
int width = Math.round((float) ratio * realImage.getWidth());
int height = Math.round((float) ratio * realImage.getHeight());
Bitmap newBitmap = Bitmap.createScaledBitmap(realImage, width,
height, filter);
return newBitmap;
}
as used here.