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); }
以上就是本文的全部内容,帮助大家轻松实现毛玻璃效果,希望大家喜欢。