Android模糊处理简单实现毛玻璃效果
自从iOS系统引入了Blur效果,也就是所谓的毛玻璃、模糊化效果、磨砂效果,各大系统就开始竞相模仿,这是怎样的一个效果呢,我们先来看一下,如下面的图片:
实现效果大家都知道了,如何在Android中实现呢,说白了就是对图片进行模糊化处理,小编先给大家讲一下Android高级模糊技术的原理,如下:
- 首先我创建了一个空的bitmap,把背景的一部分复制进去,之后我会对这个bitmap进行模糊处理并设置为TextView的背景。
- 通过这个bitmap保存Canvas的状态;
- 在父布局文件中把Canvas移动到TextView的位置;
- 把ImageView的内容绘到bitmap中;
- 此时,我们就有了一个和TextView一样大小的bitmap,它包含了ImageView的一部分内容,也就是TextView背后一层布局的内容;
- 创建一个Renderscript的实例;
- 把bitmap复制一份到Renderscript需要的数据片中;
- 创建Renderscript模糊处理的实例;
- 设置输入,半径范围然后进行模糊处理;
- 把处理后的结果复制回之前的bitmap中;
- 好了,我们已经把bitmap惊醒模糊处理了,可以将它设置为TextView背景了;
我最近在做一款App,其中有一个功能需要对图片处理实现毛玻璃的特效,经过一番研究,找到了3中实现方案,其中各有优缺点,如果系统的api在16以上,可以使用系统提供的方法直接处理图片,但是小编认为下边的解决方案是实现效果最好的。
代码如下:
publicBitmapfastblur(Contextcontext,BitmapsentBitmap,intradius){
Bitmapbitmap=sentBitmap.copy(sentBitmap.getConfig(),true);
if(radius<1){
return(null);
}
intw=bitmap.getWidth();
inth=bitmap.getHeight();
int[]pix=newint[w*h];
bitmap.getPixels(pix,0,w,0,0,w,h);
intwm=w-1;
inthm=h-1;
intwh=w*h;
intdiv=radius+radius+1;
intr[]=newint[wh];
intg[]=newint[wh];
intb[]=newint[wh];
intrsum,gsum,bsum,x,y,i,p,yp,yi,yw;
intvmin[]=newint[Math.max(w,h)];
intdivsum=(div+1)>>1;
divsum*=divsum;
inttemp=256*divsum;
intdv[]=newint[temp];
for(i=0;i<temp;i++){
dv[i]=(i/divsum);
}
yw=yi=0;
int[][]stack=newint[div][3];
intstackpointer;
intstackstart;
int[]sir;
intrbs;
intr1=radius+1;
introutsum,goutsum,boutsum;
intrinsum,ginsum,binsum;
for(y=0;y<h;y++){
rinsum=ginsum=binsum=routsum=goutsum=boutsum=rsum=gsum=bsum=0;
for(i=-radius;i<=radius;i++){
p=pix[yi+Math.min(wm,Math.max(i,0))];
sir=stack[i+radius];
sir[0]=(p&0xff0000)>>16;
sir[1]=(p&0x00ff00)>>8;
sir[2]=(p&0x0000ff);
rbs=r1-Math.abs(i);
rsum+=sir[0]*rbs;
gsum+=sir[1]*rbs;
bsum+=sir[2]*rbs;
if(i>0){
rinsum+=sir[0];
ginsum+=sir[1];
binsum+=sir[2];
}else{
routsum+=sir[0];
goutsum+=sir[1];
boutsum+=sir[2];
}
}
stackpointer=radius;
for(x=0;x<w;x++){
r[yi]=dv[rsum];
g[yi]=dv[gsum];
b[yi]=dv[bsum];
rsum-=routsum;
gsum-=goutsum;
bsum-=boutsum;
stackstart=stackpointer-radius+div;
sir=stack[stackstart%div];
routsum-=sir[0];
goutsum-=sir[1];
boutsum-=sir[2];
if(y==0){
vmin[x]=Math.min(x+radius+1,wm);
}
p=pix[yw+vmin[x]];
sir[0]=(p&0xff0000)>>16;
sir[1]=(p&0x00ff00)>>8;
sir[2]=(p&0x0000ff);
rinsum+=sir[0];
ginsum+=sir[1];
binsum+=sir[2];
rsum+=rinsum;
gsum+=ginsum;
bsum+=binsum;
stackpointer=(stackpointer+1)%div;
sir=stack[(stackpointer)%div];
routsum+=sir[0];
goutsum+=sir[1];
boutsum+=sir[2];
rinsum-=sir[0];
ginsum-=sir[1];
binsum-=sir[2];
yi++;
}
yw+=w;
}
for(x=0;x<w;x++){
rinsum=ginsum=binsum=routsum=goutsum=boutsum=rsum=gsum=bsum=0;
yp=-radius*w;
for(i=-radius;i<=radius;i++){
yi=Math.max(0,yp)+x;
sir=stack[i+radius];
sir[0]=r[yi];
sir[1]=g[yi];
sir[2]=b[yi];
rbs=r1-Math.abs(i);
rsum+=r[yi]*rbs;
gsum+=g[yi]*rbs;
bsum+=b[yi]*rbs;
if(i>0){
rinsum+=sir[0];
ginsum+=sir[1];
binsum+=sir[2];
}else{
routsum+=sir[0];
goutsum+=sir[1];
boutsum+=sir[2];
}
if(i<hm){
yp+=w;
}
}
yi=x;
stackpointer=radius;
for(y=0;y<h;y++){
pix[yi]=(0xff000000&pix[yi])|(dv[rsum]<<16)
|(dv[gsum]<<8)|dv[bsum];
rsum-=routsum;
gsum-=goutsum;
bsum-=boutsum;
stackstart=stackpointer-radius+div;
sir=stack[stackstart%div];
routsum-=sir[0];
goutsum-=sir[1];
boutsum-=sir[2];
if(x==0){
vmin[y]=Math.min(y+r1,hm)*w;
}
p=x+vmin[y];
sir[0]=r[p];
sir[1]=g[p];
sir[2]=b[p];
rinsum+=sir[0];
ginsum+=sir[1];
binsum+=sir[2];
rsum+=rinsum;
gsum+=ginsum;
bsum+=binsum;
stackpointer=(stackpointer+1)%div;
sir=stack[stackpointer];
routsum+=sir[0];
goutsum+=sir[1];
boutsum+=sir[2];
rinsum-=sir[0];
ginsum-=sir[1];
binsum-=sir[2];
yi+=w;
}
}
bitmap.setPixels(pix,0,w,0,0,w,h);
return(bitmap);
}
以上就是本文的全部内容,帮助大家轻松实现毛玻璃效果,希望大家喜欢。