In my android application, I upload and download JPEG images. For some images BitmapFactory
downsamples the downloaded image and I don't understand why and how to stop it from doing so.
I log the Bitmap object size when I upload and download the images:
Uploading image with size 3840x2160
Opening received image of size 2601584B degradation 0 decoded 384x216
So here my image width and height are divided by 10 after decoding by BitmapFactory
.
For another image I go from 3480x4640 to 217x290, so a division by 16. I first thought it could be caused by image dpi metadata, so I tried to force it when opening the image with the following code:
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inSampleSize = 1 << degradation;
opts.inScaled = false;
opts.inDensity = 1;
opts.inTargetDensity = 1;
opts.inScreenDensity = 1;
final Bitmap original = BitmapFactory.decodeByteArray(data, 0, data.length, opts);
Log.d(Tags.IMAGES, "Opening received image of size " + data.length + " degradation " + degradation + " decoded " + original.getWidth() + "x" + original.getHeight());
As you can see the number of bytes (2MB) I give the BitmapFactory
is consistent with a large image not with a 300x200px image. So my uploading code and downloading code are correct I have the right data before decoding.
I forced all the densities to avoid scaling and also disabled scaling and my sample size is 1 since my degradation is 0 so I don't force any subsampling. I still end with a very small image. And BitmapFactory.decodeByteArray
quickly calls native code so I can't really debug that.
I tried:
BitmapFactory.Options
object to 0 but this didn't change a thing. decodeByteArray
method, still the image is too small.Ok after more investigation I found the issue and it was due to another part of the code. Due to a race condition in the application I was writing to the same file the image and a miniature of it concurrently. So I ended up with a large image file but its beginning was overridden with a small image, and this is why BitmapFactory creates this small image. Sorry the issue was not in this part of the code so you couldn't find it.