仅模糊不模糊图像而不是文本或其他

穆尔加德

我有一个BlurActionBarDrawerToggle模糊我的背景,当我打开抽屉式导航栏:

public class BlurActionBarDrawerToggle extends ActionBarDrawerToggle {
    public static int DEFAULT_BLUR_RADIUS = 25;
    public static float DEFAULT_DOWNSCALEFACTOR = 8.0f;
    private Context context = null;
    private DrawerLayout drawerLayout = null;
    private ImageView blurredImageView = null;
    private int blurRadius = DEFAULT_BLUR_RADIUS;
    private float downScaleFactor = DEFAULT_DOWNSCALEFACTOR;
    private boolean prepareToRender = true;
    private boolean isOpening = false;

    public BlurActionBarDrawerToggle(Activity activity, DrawerLayout drawerLayout, int openDrawerContentDescRes, int closeDrawerContentDescRes) {
        super(activity, drawerLayout, openDrawerContentDescRes, closeDrawerContentDescRes);

        this.context = activity.getBaseContext();
        this.drawerLayout = drawerLayout;

        this.init();
    }

    public BlurActionBarDrawerToggle(Activity activity, DrawerLayout drawerLayout, Toolbar toolbar, int openDrawerContentDescRes, int closeDrawerContentDescRes) {
        super(activity, drawerLayout, toolbar, openDrawerContentDescRes, closeDrawerContentDescRes);

        this.context = activity.getBaseContext();
        this.drawerLayout = drawerLayout;

        this.init();
    }

    private void init() {
        this.blurredImageView = new ImageView(context);
        this.blurredImageView.setLayoutParams(new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        this.blurredImageView.setClickable(false);
        this.blurredImageView.setVisibility(View.GONE);
        this.blurredImageView.setScaleType(ImageView.ScaleType.FIT_XY);

        this.drawerLayout.setScrimColor(this.context.getResources().getColor(android.R.color.transparent));
        this.drawerLayout.post(new Runnable() {
            @Override
            public void run() {
                drawerLayout.addView(blurredImageView, 1);
            }
        });
    }

    @Override
    public void onDrawerSlide(final View drawerView, final float slideOffset) {
        super.onDrawerSlide(drawerView, slideOffset);

        if (slideOffset == 0.f) {
            this.isOpening = false;
        } else {
            this.isOpening = true;
        }

        this.render();
        this.setAlpha(this.blurredImageView, slideOffset, 100);
    }

    @Override
    public void onDrawerClosed(View view) {
        this.prepareToRender = true;
        this.blurredImageView.setVisibility(View.GONE);
    }

    @Override
    public void onDrawerStateChanged(int newState) {
        super.onDrawerStateChanged(newState);

        if (newState == DrawerLayout.STATE_IDLE && !this.isOpening) {
            this.handleRecycle();
        }
    }

    private void render() {
        if (this.prepareToRender) {
            this.prepareToRender = false;

            Bitmap bitmap = loadBitmapFromView(this.drawerLayout);
            bitmap = scaleBitmap(bitmap);
            bitmap = Blur.fastblur(this.context, bitmap, this.blurRadius, false);

            this.blurredImageView.setVisibility(View.VISIBLE);
            this.blurredImageView.setImageBitmap(bitmap);
        }

    }

    public void setRadius(int radius) {
        this.blurRadius = radius < 1 ? 1 : radius;
    }

    public void setDownScaleFactor(float downScaleFactor) {
        this.downScaleFactor = downScaleFactor < 1 ? 1 : downScaleFactor;
    }

    private void setAlpha(View view, float alpha, long durationMillis) {
        final AlphaAnimation animation = new AlphaAnimation(alpha, alpha);

        animation.setDuration(durationMillis);
        animation.setFillAfter(true);

        view.startAnimation(animation);
    }

    private Bitmap loadBitmapFromView(View view) {
        Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);

        Canvas canvas = new Canvas(bitmap);

        view.draw(canvas);

        return bitmap;
    }

    private Bitmap scaleBitmap(Bitmap myBitmap) {
        int width = (int) (myBitmap.getWidth() / this.downScaleFactor);
        int height = (int) (myBitmap.getHeight() / this.downScaleFactor);

        return Bitmap.createScaledBitmap(myBitmap, width, height, false);
    }

    private void handleRecycle() {
        Drawable drawable = this.blurredImageView.getDrawable();

        if (drawable instanceof BitmapDrawable) {
            BitmapDrawable bitmapDrawable = ((BitmapDrawable) drawable);
            Bitmap bitmap = bitmapDrawable.getBitmap();

            if (bitmap != null) {
                bitmap.recycle();
            }

            this.blurredImageView.setImageBitmap(null);
        }

        this.prepareToRender = true;
    }
}

使用此Blur方法:

public class Blur {

    public static Bitmap fastblur(Context context, Bitmap sentBitmap, int radius, boolean canReuseInBitmap) {
        Bitmap bitmap = sentBitmap.copy(sentBitmap.getConfig(), true);

        final RenderScript renderScript = RenderScript.create(context);
        final Allocation input = Allocation.createFromBitmap(renderScript, sentBitmap, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);

        final Allocation output = Allocation.createTyped(renderScript, input.getType());
        final ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(renderScript, Element.U8_4(renderScript));

        script.setRadius(radius);
        script.setInput(input);
        script.forEach(output);

        output.copyTo(bitmap);

        return bitmap;
    }
}

不幸的是,这仅会使背景图像等图像模糊。下图显示了具有图像背景的视图的模糊:

在此处输入图片说明

第二张图片在没有任何图像的视图上显示了相同的导航抽屉和actionbardrawertoggle:

在此处输入图片说明

如您所见,这里没有什么模糊的。有人可以告诉我这里出了什么问题吗?

马蒂阿什

这实际上是三个因素的组合:

  1. 在模糊之前,将图像缩小比例(默认情况下缩小8倍)。这意味着非常薄的文本被缩小到很小的尺寸
  2. 然后,模糊将这些少量的彩色像素“分散”到更大的区域(因子为25),这意味着模糊的文本几乎不可察觉
  3. ImageView背景是透明的,因此“真实的” TextView在模糊图像的后面仍然可见(由于1和2,在该区域中大多数情况下是透明的)。

最简单的解决方法是为设置背景色,并blurredImageView使用与活动背景色相同的值。如果没有其他更改,则意味着其他UI元素(文本,行和&c)将被隐藏。例如,在render()

this.blurredImageView.setVisibility(View.VISIBLE);
this.blurredImageView.setImageBitmap(bitmap);
this.blurredImageView.setBackgroundColor(Color.RED);  // added

如果要使其模糊但仍隐约可见,请减小缩小比例因子和半径,例如:

mDrawerToggle.setDownScaleFactor(2);
mDrawerToggle.setRadius(10);

但是,请注意,这也将减少图像的模糊(以及为位图消耗更多的内存)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

模糊div会模糊其他div

来自分类Dev

模糊div会模糊其他div

来自分类Dev

仅模糊输入中的文本,而不是整个<input>元素

来自分类Dev

单击其他元素时模糊(不聚焦)某个元素

来自分类Dev

如何模糊图像中的文本?

来自分类Dev

模糊与图像视图的大小不匹配Swift

来自分类Dev

模糊与图像视图的大小不匹配Swift

来自分类Dev

Microsoft PowerPoint:导入图像中的文本模糊

来自分类Dev

带有文本的悬停 HTML 模糊图像?

来自分类Dev

CGContextRef绘制模糊或模糊的图像

来自分类Dev

UILabel仅模糊文字

来自分类Dev

AngularJS || 当执行其他会模糊的功能时,忽略ngBlur对元素的模糊

来自分类Dev

如何仅模糊背景而不覆盖Ionic / CSS中的内容

来自分类Dev

模糊而不是锐化

来自分类Dev

模糊而不是锐化

来自分类Dev

Elasticsearch不模糊

来自分类Dev

CSS 背景图像呈现模糊而不是完全

来自分类Dev

如何防止单击按钮使其他元素变得模糊?

来自分类Dev

如何关闭使其他元素模糊的永久元素?

来自分类Dev

等离子中的某些字体模糊,其他则不

来自分类Dev

摇摆模糊拖曳图像

来自分类Dev

检测图像的模糊程度

来自分类Dev

模糊图像的选定部分

来自分类Dev

如何检查图像模糊?

来自分类Dev

用C模糊图像

来自分类Dev

模糊图像的单面

来自分类Dev

模糊图像JavaScript

来自分类Dev

用python模糊图像

来自分类Dev

中央模糊的图像