kikoso / android-stackblur

Android StackBlur is a library that can perform a blurry effect on a Bitmap based on a gradient or radius, and return the result. The library is based on the code of Mario Klingemann.
Apache License 2.0
3.59k stars 647 forks source link

Excessive GC use #19

Open Dr-Emann opened 10 years ago

Dr-Emann commented 10 years ago

The Garbage Collector is being run (GC_FOR_MALLOC) on every blur because we're creating a new bitmap on every call. There's two ways to try to fix this.

Explicit Bitmap Re-use

The usual solution to this problem is to allow the user to pass an existing bitmap in.

StackBlurManager manager = new StackBlurManager(bitmap);
Bitmap output = Bitmap.createBitmap(
    bitmap.getWidth(),
    bitmap.getHeight,
    Bitmap.Config.ARGB_8888
);
manager.process(10, output);

Pros

However, because we have the StackBlurManager class which already holds a reference to the result, we could possibly reuse that bitmap. This could possibly break some existing code though! If the user holds on to a reference to the blurred bitmap, then blurs again, the first reference will be modified to be the same as the second. For example:

StackBlurManager manager = new StackBlurManager(bitmap);
Bitmap blur5px = manager.process(5);
Bitmap blur10px = manager.process(10);
// blur5px and blur10px are the same Bitmap, and both are blurred by 10px.
// The user would have to explicitly copy the bitmap if they want control of it.
Bitmap correct_blur5px = manager.process(5).copy(Bitmap.Config.ARGB_8888, false);

Another possible problem arises if the user tries to recycle the image.

StackBlurManager manager = new StackBlurManager(bitmap);
Bitmap tmp = manager.process(5);
tmp.recycle();
// User thinks they're cleaning up after themselves, but the bitmap is
// owned by the StackBlurManager.

The StackBlurManager can check if the image has been recycled before trying to blur into it, and make a new bitmap if it has been, possibly putting something in the log letting the user know they shouldn't call recycle on bitmaps owned by the manager.

Pros

kikoso commented 10 years ago

Hello @Dr-Emann ,

I would say the explicit option has bigger advantages rather than the implicit. We are supporting existing code, but from now on the user can also use a new feature to improve performance - in the case he was having performance problems, I do not think this will happen if they are blurring single images.

What are your thoughts?

Dr-Emann commented 10 years ago

I agree. I've set up something here: https://github.com/Dr-Emann/android-stackblur/tree/less_garbage. I'll have to clean it up a little, and submit a pull request.

kikoso commented 10 years ago

Cool :-). Looking forward!

randomrandom commented 10 years ago

Hi guys, I'm currently experiencing Out of memory exceptions. I use your library to blur single images in separate activities, but it seems that on lower-end devices this causes out of memory exceptions after some time. I managed to reduce the exceptions by scaling down the image 3 times before I pass to the StackBlur and then scaling it back to normal, but this produces lower image quality. Do you have any progress on the issue? I'm currently using the .process(radius) method. I haven't tried the processNatively method, do you think it would make a difference?

kikoso commented 10 years ago

Hello @randomrandom ,

Old and low end devices might have problems running the library. Are you running the Java method? Running the NDK or RenderScript process definitely helps in terms of optimization, but still some devices might not be able to process it.

http://developer.android.com/training/displaying-bitmaps/index.html

I fear that in that case the only solution is to reduce the image size