Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

the blurview draw the overlayColor is incorrect #203

Open
ncwuguowei opened this issue Aug 18, 2023 · 3 comments
Open

the blurview draw the overlayColor is incorrect #203

ncwuguowei opened this issue Aug 18, 2023 · 3 comments

Comments

@ncwuguowei
Copy link

Please include:

  1. Library version
    master branch
    2). the blurview draw the overlayColor is incorrect.
    PreDrawBlurController#public boolean draw(Canvas canvas) {
    ....
    canvas.restore();
    // NOTE: need delete there, because only draw overlayColor to blurView content.
    // current canvas.drawColor(overlayColor) will cause the whole canvas(decorView) draw the overlayColer
    if (overlayColor != TRANSPARENT) {
    canvas.drawColor(overlayColor);
    }
    return true;
    }

and method blurAndSave() to add draw overlayColor ,mix to bulred bitmap

private void blurAndSave() {
    internalBitmap = blurAlgorithm.blur(internalBitmap, blurRadius);
    if (!blurAlgorithm.canModifyBitmap()) {
        internalCanvas.setBitmap(internalBitmap);
    }
    //NOTE: modify only draw overlayColor to blurView content
    if (overlayColor != TRANSPARENT) {
        internalCanvas.drawColor(overlayColor);
    }
}
@Dimezis
Copy link
Owner

Dimezis commented Aug 18, 2023

Post your setup.
Normally it shouldn't matter, since the bitmap from internalCanvas is then being drawn on the system canvas anyway.
And drawing on canvas is also confined within the view bounds

@ncwuguowei
Copy link
Author

Hi, I found the cause of the problem.

  1. the overlayColor should be mixed with the Gaussian blurred graph(note:internalBitmap or internalCanvas)
    because when the whole root view draw, current only change the bluredView by onPreDraw ,
    but when draw blurView itself, draw(Canvas canvas) is return
    @OverRide
    public boolean draw(Canvas canvas) {
    if (!blurEnabled || !initialized) {
    return true;
    }
    // Not blurring itself or other BlurViews to not cause recursive draw calls
    // Related: java.lang.IndexOutOfBoundsException: Index: 6, Size: 0 #110
    if (canvas instanceof BlurViewCanvas) {
    return false;
    }
    ...
    if (overlayColor != TRANSPARENT) {
    canvas.drawColor(overlayColor);
    }
    }

canvas.drawColor(overlayColor) , here can not execute. so the overlayColor can not draw.

  1. canvas.drawColor(overlayColor) is no size specified, the whole canvas draw the color.
    commonly we can not find this bug because the parent setClipChildren(true) by default,
    but when set setClipChildren(false), you can see the error.

I set the overlayColor is RED for demo

when RN setClipChildren(false) default
image

when setClipChildren(true) for example

blurView.postDelayed(new Runnable() {
  @Override
  public void run() {
    Log.i("AndroidBlurView", "blurView width = " + blurView.getWidth() +
            " ,blurView height = " + blurView.getHeight());
    ViewGroup parent = (ViewGroup) blurView.getParent();
    parent.setClipChildren(true);
  }
}, 10 * 1000);

image

3.the error exist in React Native project , but I can not find in normal andord project even I set setClipChildren(false),
why it draw in correct whthin the view bounds?

  1. so we should draw overlayColor with correct size and draw in onPrewDraw() by updateBlur().

this React Native project use BlurView in Android , you can see this
https://github.com/Kureev/react-native-blur

@ncwuguowei
Copy link
Author

ncwuguowei commented Aug 21, 2023

Ha ha, I can show error in your demo ~~~
Only drop outline provider in MainActivity, and set clicpChildren(false)

  1. main_activity.xml , set root view clipChildren(false)
    image

  2. MainActivity.java
    drop the outline code , and to set overlayColor Red show clearly.
    private void initView() {
    viewPager = findViewById(R.id.viewPager);
    tabLayout = findViewById(R.id.tabLayout);
    bottomBlurView = findViewById(R.id.bottomBlurView);
    topBlurView = findViewById(R.id.topBlurView);
    // Rounded corners + casting elevation shadow with transparent background
    // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    // topBlurView.setClipToOutline(true);
    // topBlurView.setOutlineProvider(new ViewOutlineProvider() {
    // @OverRide
    // public void getOutline(View view, Outline outline) {
    // topBlurView.getBackground().getOutline(outline);
    // outline.setAlpha(1f);
    // }
    // });
    // }
    radiusSeekBar = findViewById(R.id.radiusSeekBar);
    root = findViewById(R.id.root);
    }

image

I think the outline affect the bulrView draw, so the demo usually can not find this bug.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants