Android高斯模糊技术,实现毛玻璃效果

0?wx_fmt=gif&wxfrom=5&wx_lazy=1
 

本示例是在ConvenientBanner这个开源库demo上改的,自己写一个浪费时间,直接拿来用,地址为:

https://github.com/saiwu-bigkoo/Android-ConvenientBanner

 

在找遍了所有高斯模糊的算法代码后,发现android-stackblur的java实现是最快的,地址为:

https://github.com/kikoso/android-stackblur

 

先说一下大致思路,非常简单。模糊的区域其实是一张ImageView,当视图发生变化,在滚动的时候,截取ImgeView下面的视图,进行模糊处理,然后放在ImageView上,下面说一下细节:

 

因为要实时监听banner控件在发生变化,所以我用到了这个方法:

ViewTreeObserver.OnScrollChangedListener

见名知意,当发生滚动的时候,进行回调。那给谁设置监听器呢?谁发生变化就给谁设置监听器:

convenientBanner = (ConvenientBanner) findViewById(R.id.convenientBanner);
observer = convenientBanner.getViewTreeObserver();
observer.addOnScrollChangedListener(listener);

这个convenientBanner就是一个LinearLayout的封装,就是现实滑动图片的控件。

 

接下来先截取被ImageView盖住的部分,然后进行模糊处理:

ViewTreeObserver.OnScrollChangedListener listener =
         new ViewTreeObserver.OnScrollChangedListener() {
    @Override
    public void onScrollChanged() {
        convenientBanner.setDrawingCacheEnabled(true);
        convenientBanner.buildDrawingCache();
        Bitmap bitmap = convenientBanner.getDrawingCache();//截取区域视图
        int x = (int) imageView.getX();
        int y = (int) imageView.getY();
        int bitmapX = bitmap.getWidth();
        int bitmapY = bitmap.getHeight();
        Bitmap bitmap1 = Bitmap.createBitmap(bitmap,x,y,bitmapX-x,bitmapY-y);
        if (bitmap != null) {
            blur(bitmap1,imageView,8);//模糊处理
        }
        bitmap1.recycle();
        convenientBanner.setDrawingCacheEnabled(false);//清除缓存
    }
};

 

Bitmap bitmap = convenientBanner.getDrawingCache();//截取区域视图

是获取Imageview盖住的区域图片,但为什么要用convenientBanner,因为视图是显示在convenientBanner视图树里头的,通过计算 :

int x = (int) imageView.getX(); 
int y = (int) imageView.getY(); 
int bitmapX = bitmap.getWidth(); 
int bitmapY = bitmap.getHeight(); 
Bitmap bitmap1 = Bitmap.createBitmap(bitmap,x,y,bitmapX-x,bitmapY-y);

进行截取,createBitmap的第2个跟第3个参数是距离屏幕左跟上的距离,第4个跟第5个参数是裁剪后的宽高,千万别设置错了,数值绝对不能大于bitmapX ,bitmapY ,会抛出异常。

 

然后调用:

blur(bitmap1,imageView,8);//模糊处理

方法进行处理,这个8是模糊半径 。

 

blur的代码为:

private void blur(Bitmap bkg, ImageView view, float radius) {
    int scaleFactor = 8;
    if (overlay != null) {
        overlay.recycle();
    }
    overlay = Bitmap.createScaledBitmap(bkg, bkg.getWidth() / scaleFactor, bkg.getHeight() / scaleFactor, false);
    overlay = process.blur(overlay, radius);//高斯模糊
    view.setImageBitmap(overlay);
}

其中,process对象是一个JavaBlurProcess类的实例,这个类来自于android-stackblur开源库,里面封装了高斯模糊的具体逻辑。

 

因为高斯模糊效率的快慢取决于图片的像素点的多少,所以我进行了8倍的缩小, 为什么调用了createScaledBitmap而不是compress呢,因为compress是对成像质量做处理,并不能真正意义上的减少像素点。 

 

这里缩放为8,模糊半径为8,缩放的值越大,你半径就要要设的越大,但不能设置比1小,要不就没效果了。模糊半径约小,图片效果越清晰。如果图片压缩的太小,像素块就会看起来越来越大,如果模糊半径越小,即使模糊了,也会有像素块的效果,所以我调成两个8感觉好不错,你们回去也可以自己调。

转载于:https://my.oschina.net/JiangTun/blog/915293

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值