RedApparat / Fotoapparat

Making Camera for Android more friendly. 📸
Apache License 2.0
3.81k stars 405 forks source link

Fix unused inSampleSize and add scaling to decoding step #359

Closed Raenar4k closed 2 years ago

Raenar4k commented 5 years ago

I'm looking for ways to optimise memory usage in my app, and found some things in BitmapPhotoTransformer that i think can be improved.

1) There is inSampleSize calculation being done for decoding options, but it is never used because of typo.

2) We can skip creating another bitmap with Bitmap.createScaledBitmap if we add scaling step to decoding.

This way, if we want to scale down image while retaining original aspect ratio we skip Bitmap.createScaledBitmap, thus avoiding another bitmap allocation.

If we need to scale irregardless of aspect ratio, then createScaledBitmap will be used, but on already scaled down by biggest side version of the image, which is also a plus.

I also tried to measure performance benefit of memory usage. I've modified sample to use .toBitmap(scaled(scaleFactor = 0.22f)) Otherwise scaleFactor pf 0.25 results in inSampleSize = 4, which wouldn't need any scaling afterwards.

Not saying this is accurate (not sure how to really measure it here), but you can see that it does have some effect.

So, sample without changes is about 180-200MB: (uses createScaledBitmap) https://i.imgur.com/JjtFVGf.png

Sample that first downsamples by inSampleSize and then scales by createScaledBitmap is about 107-120MB: https://i.imgur.com/T49QVbD.png

Sample that downsamples and scales in one step and skips allocation of createScaledBitmap: is about 98-102MB: https://i.imgur.com/4AI1jMU.png

Diolor commented 5 years ago

This looks good to me. Very nice improvement @Raenar4k, thanks! 👍 @dmitry-zaitsev wanna take a look in this one too?