Dimezis / BlurView

Dynamic iOS-like blur of underlying Views for Android
Apache License 2.0
3.49k stars 331 forks source link

Feature Request: Smooth blurring with no popping #161

Open izackp opened 2 years ago

izackp commented 2 years ago

Let's say you have a blue background with a red rectangle moving. Once the red rectangle reaches the blue view then moves 1 pixel underneath it BAM the whole area is now has a red tint. High contrast elements will flash in and out as the user scrolls which become noticeable.

https://gfycat.com/fatalgroundedjanenschia

Dimezis commented 2 years ago

How do you imagine this can be fixed?

You have a bitmap with View snapshot, let's say 100x100, pure white. Blurring it produces a pure white bitmap again.

Next frame, the top 1-2 rows of pixels become red. You blur this bitmap with a radius of 20 pixels, and the red color spreads down by 20 pixels give or take.

The effect is then exaggerated because of the need to downscale the original bitmap to produce the blur in a reasonable amount of time. Blurring a full-sized bitmap would help to mitigate this by a large amount, but most of budget+ Android devices would choke on that

izackp commented 2 years ago

Hmm I thought about two ways but they both seem like a pain

Both don't really seem like easy fixes tho, since you're using a built-in algorithm to do the blurring.

Dimezis commented 2 years ago

However, I don't really like the idea of having the blur change color before an image gets under it.

Yes, it's a fundamental problem of this kind of approach

Weighting the blur radius based on distance from an edge

While it might seem like a remedy for this particular case, it will produce weird/incorrect results in general.

To really fix this the BlurView needs to stop downscaling the view hierarchy to speed up the blur, but with all the limitations Android imposes, that's just not realistic for weaker devices.

Thanks for the suggestions though!

Dimezis commented 2 years ago

This is somewhat addressed for API >= 31 in version 2.0.0 with the new RenderEffectBlur. It's still not ideal, also barely tested, but you can try it out