一. 简介
对图片做高斯模糊,有非常多的方法
高斯模糊的计算量很大,为减少计算时间,有两种优化途径:
1.使用render script,并对高斯算法做优化
2.使用jni,在c层对图片做处理
后者的优点是兼容android 1.x,前者只能在android 2.2以上版本才能运行
对我们来说,使用render script就好了
注意:模糊半径,根据原图尺寸设置,一般设置为原图尺寸的15%-30%效果比较好,例如
![](http://wiki.letv.cn/download/attachments/44527804/RSStackBlur_kikoso_3%20radius_99.png?version=2&modificationDate=1428928485000&api=v2)
![](http://wiki.letv.cn/download/attachments/44527804/RSStackBlur_kikoso_1%20radius_51.png?version=2&modificationDate=1428928481000&api=v2)
![](http://wiki.letv.cn/download/attachments/44527804/50.png?version=4&modificationDate=1428928471000&api=v2)
原图大小 540*960px radius = 50px radius = 100px
![](http://wiki.letv.cn/download/attachments/44527804/RSStackBlur_kikoso_7%20radius_60.png?version=1&modificationDate=1428928586000&api=v2)
![](http://wiki.letv.cn/download/attachments/44527804/RSStackBlur_kikoso_8%20radius_39.png?version=1&modificationDate=1428928581000&api=v2)
![](http://wiki.letv.cn/download/attachments/44527804/RSStackBlur_kikoso_6%20radius_19.png?version=1&modificationDate=1428928577000&api=v2)
![](http://wiki.letv.cn/download/attachments/44527804/bitmap1427960918823.jpg?version=1&modificationDate=1428928542000&api=v2)
原图大小 200*200px radius = 20px radius = 40px radius = 60px
二. 类介绍
即使是使用render script,做高斯模糊的方法也有很多种,
在此,推荐两种方法:
1.使用google原生代码中的高斯模糊类ScriptIntrinsicBlur,radius 范围为 1-25px
2.使用 kikoso 整理的stack 高斯算法,radius 范围为 1-254px
我对这两种方法都做了封装,方便大家调用,一共提供了三个类,
RSGaussianBlur(使用google原生代码中的高斯模糊类ScriptIntrinsicBlur)
RSStackBlur_kikoso(使用 kikoso 整理的stack 高斯算法)
这两个类都implement了IBlur 接口,
publicinterfaceIBlur {
/**
* 给定一个bitmap,以及模糊半径,对图片做模糊后返回一张模糊后的bitmap
* 一般来说,返回的bitmap与给定的bitmap不是同一个,你必须自己回收这个新的bitmap
* 因为render script限制,返回的bitmap宽度会是4的倍数,
* 例如,如果原图宽度为202px,返回的bitmap宽度为200px
*/
publicBitmap blur(intradius, Bitmapin);
/**
* 给定一个bitmap,以及模糊半径,对图片做模糊后返回一张模糊后的bitmap
* 一般来说,返回的bitmap与给定的bitmap不是同一个,你必须自己回收这个新的bitmap
*@paraminSampleSize 如果大于1,先压缩原图,然后做模糊,返回的新bitmap大小比原图小,
* 如果小于等于1,则忽略该参数
* 例如,inSampleSize 为 4,新建一个bitmap,宽高各为原图1/4,并将宽度调整为4的倍数,
* 同时使用新的模糊半径 radius/4, 对新bitmap 做模糊后返回这个新bitmap
* 使用这个类有两个好处:
* 1. 反正是模糊图,先压缩再模糊,效果基本一样,但是时间消耗大量减少,建议 inSampleSize为4
* 例如,原图宽度小于1080px,inSampleSize为4,原图宽度到达1440px,取6或8
* 2. 对RSGaussianBlur类,可使用blur(100,in, 4);,从而突破了半径不能超过25px的限制
*/
publicBitmap blur(intradius, Bitmapin,intinSampleSize);
/**
* 使用完类后,必须调用该方法释放render script资源,
* 否则每次new一个新对象,有增加1个新的render script线程和占用一堆资源
* 至于返回的bitmap,由你自己管理,在此并没有去释放那个bitmap
*/
publicvoidrecycle();
/**
* 获取你上次调用 blur() 所花的时间
*/
publiclonggetTimeMs();
}
在模糊半径比较小的时候,你随便用哪个类都可以,
但是,如果模糊半径太大,你又不希望原图压缩太多的话,使用RSStackBlur_kikoso 更合适
例如,原图大小为1920*1080,模糊半径为100,使用这两个没什么区别
但是,1)如果原图为100*100,模糊半径为100,如果使用RSGaussianBlur,则必须设置inSampleSize参数为4,
即先将原图压缩为 24*25 的小图,然后做模糊,这将导致模糊出来的效果很差,因为压缩图太小,细节全没了
这种情况下必须用RSStackBlur_kikoso,设置inSampleSize参数为1,即不要压缩原图,反正它很小
三 类文件和用法
1.将下面压缩包中的几个文件copy到你的目录下
并修改各个类的import为你的包名,
最后将stackblur_kikoso.rs文件中的
#pragmarsjava_package_name(com.monster.blur.algorithm)
修改为:
#pragmarsjava_package_name(你自己的包名)
2.在代码中调用即可
IBluriBlur=newRSGaussianBlur(this); 或IBluriBlur=newRSStackBlur_kikoso(this);
intradius= 60;
Bitmapin= ...;
intinSampleSize= 4;
iBlur.blur(radius,in,inSampleSize);// 在调用 iBlur.recycle()之前,可反复使用blur()函数
iBlur.recycle();
网友评论