android背景模糊化处理

import java.io.FileOutputStream;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.Surface;
import android.view.SurfaceControl;
import android.view.WindowManager;

public class StackBlurManager {
	private static final String TAG = "StackBlurManager";
	private static final int DEFAULT_SCALE = 8;

	/**
	 * Original set of pixels from the image
	 */
	private int [] originalPixels;
	/**
	 * Current set of pixels from the image (the one that will be exported
	 */
	private int [] currentPixels;
	/**
	 * Original width of the image
	 */
	private int _width = -1;
	/**
	 * Original height of the image
	 */
	private int _height= -1;
	/**
	 * Original image
	 */
	private Bitmap _image;

	private boolean alpha = true;
	private Context mContext;
	
	public StackBlurManager(Context context){
		mContext = context;
	}

	private void init(Bitmap image) {
		_width=image.getWidth();
		_height=image.getHeight();
		_image = image;

		originalPixels= new int[_width*_height];

		_image.getPixels(originalPixels, 0, _width, 0, 0, _width, _height);
	}
	private void process(int radius) {
		if (radius < 1 )
			radius = 1;
		currentPixels = originalPixels.clone();
		int wm=_width-1;
		int hm=_height-1;
		int wh=_width*_height;
		int div=radius+radius+1;

		int r[]=new int[wh];
		int g[]=new int[wh];
		int b[]=new int[wh];
		int rsum,gsum,bsum,x,y,i,p,yp,yi,yw;
		int vmin[] = new int[Math.max(_width,_height)];

		int divsum=(div+1)>>1;
		divsum*=divsum;
		int dv[]=new int[256*divsum];
		for (i=0;i<256*divsum;i++){
			dv[i]=(i/divsum);
		}

		yw=yi=0;

		int[][] stack=new int[div][3];
		int stackpointer;
		int stackstart;
		int[] sir;
		int rbs;
		int r1=radius+1;
		int routsum,goutsum,boutsum;
		int rinsum,ginsum,binsum;

		for (y=0;y<_height;y++){
			rinsum=ginsum=binsum=routsum=goutsum=boutsum=rsum=gsum=bsum=0;
			for(i=-radius;i<=radius;i++){
				p=currentPixels[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<_width;x++){

//				if (!alpha)
//					alpha = (int)(Color.alpha(originalPixels[y*_height+x]))  != 255;

				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=currentPixels[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+=_width;
		}
		for (x=0;x<_width;x++){
			rinsum=ginsum=binsum=routsum=goutsum=boutsum=rsum=gsum=bsum=0;
			yp=-radius*_width;
			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+=_width;
				}
			}
			yi=x;
			stackpointer=radius;
			for (y=0;y<_height;y++){
				// Preserve alpha channel: ( 0xff000000 & pix[yi] )
				if ( alpha )
					currentPixels[yi] = (0xff000000 & currentPixels[yi]) | (dv[rsum] << 16) | (dv[gsum] << 8) | dv[bsum];
				else
					currentPixels[yi]=0xff000000 | (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)*_width;
				}
				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+=_width;
			}
		}

	}

	/**
	 * Returns the blurred image as a bitmap
	 * @return blurred image
	 */
	private Bitmap returnBlurredImage() {
		Bitmap newBmp = Bitmap.createBitmap(_image.getWidth(), _image.getHeight(), Config.ARGB_8888);
		Canvas c = new Canvas(newBmp); 

		c.drawBitmap(_image, 0, 0, new Paint());
		newBmp.setPixels(currentPixels, 0, _width, 0, 0, _width, _height);
		return newBmp;
	}

	/**
	 * Save the image into the file system
	 * @param path The path where to save the image
	 */
	private void saveIntoFile(String path) {
		Bitmap newBmp = Bitmap.createBitmap(_image.getWidth(), _image.getHeight(), Config.ARGB_8888);
		Canvas c = new Canvas(newBmp); 
		c.drawBitmap(_image, 0, 0, new Paint());

		newBmp.setPixels(currentPixels, 0, _width, 0, 0, _width, _height);

		try {
			FileOutputStream out = new FileOutputStream(path);
			newBmp.compress(Bitmap.CompressFormat.PNG, 90, out);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Returns the original image as a bitmap
	 * @return the original bitmap image
	 */
	private Bitmap getImage() {
		return this._image;
	}
	
    private static Bitmap zoomBitmap(Bitmap bitmap, int w, int h) {
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        Matrix matrix = new Matrix();
        float scaleWidht = ((float) w / width);
        float scaleHeight = ((float) h / height);
        matrix.postScale(scaleWidht, scaleHeight);
        Bitmap newbmp = Bitmap.createBitmap(bitmap, 0, 0, width, height,
                matrix, true);
        return newbmp;
    }

	//获取模糊图片  (注调用该函数后,需要在窗口销毁时调用 destroy()函数释放资源)  
	public Bitmap GetBlurredBitmap(int bgWidth, int bgHeight, int scale){
    	Bitmap bitmap;
    	Bitmap newBmp;
    	Matrix matrix = new Matrix();
    	int screenWidth;
    	int screenHeight;
    	int rotation;

		if(scale == -1){
			scale = DEFAULT_SCALE;
		}
    	
    	if(_image != null){
    		_image.recycle();
    		_image = null;
    	}
    	
        
    	//1、创建截屏图片
    	WindowManager windowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);  
    	Display display = windowManager.getDefaultDisplay();  
    	DisplayMetrics displayMetrics = new DisplayMetrics();  
    	display.getRealMetrics(displayMetrics); 
    	screenWidth = displayMetrics.widthPixels;
    	screenHeight = displayMetrics.heightPixels;
    	rotation = display.getRotation();
    	Log.i(TAG, "screenWidth = "+screenWidth+" screenHeight = "+screenHeight);
          
        float[] dims = {screenWidth, screenHeight};  
        float degrees = getDegreesForRotation(rotation);  
        boolean requiresRotation = (degrees > 0);  
        if (requiresRotation) {  
            // Get the dimensions of the device in its native orientation  
        	matrix.reset();  
        	matrix.preRotate(-degrees);  
        	matrix.mapPoints(dims);  
            dims[0] = Math.abs(dims[0]);  
            dims[1] = Math.abs(dims[1]);  
        }  
 
        bitmap = SurfaceControl.screenshot((int) dims[0], (int) dims[1]);  
        if (requiresRotation) {  
            // Rotate the screenshot to the current orientation  
            Bitmap tmpBitmap = Bitmap.createBitmap(screenWidth,  screenHeight, Bitmap.Config.ARGB_8888);  
            Canvas c = new Canvas(tmpBitmap);  
            c.translate(tmpBitmap.getWidth() / 2, tmpBitmap.getHeight() / 2);  
            c.rotate(degrees);  
            c.translate(-dims[0] / 2, -dims[1] / 2);  
            c.drawBitmap(bitmap, 0, 0, null);  
            c.setBitmap(null);
            
            bitmap.recycle();
            
            bitmap = tmpBitmap;  
        }
        // If we couldn't take the screenshot, notify the user  
        if (bitmap == null) {               
            return null;  
        }
        // Optimizations  
        bitmap.setHasAlpha(false);  
        bitmap.prepareToDraw();
        
    	Log.i(TAG, "bitmap.width = "+bitmap.getWidth()+" bitmap.getHeight = "+bitmap.getHeight());
    	newBmp = bitmap;
    	/*if(bgHeight < screenHeight){
            newBmp = Bitmap.createBitmap(bgWidth, bgHeight, Bitmap.Config.ARGB_8888);
            newBmp.setDensity(DisplayMetrics.DENSITY_DEVICE);
            Canvas canvas = new Canvas(newBmp);
            canvas.setDensity(DisplayMetrics.DENSITY_DEVICE);
            canvas.drawBitmap(bitmap, 0, screenHeight - bgHeight, null);
            bitmap.recycle();
            bitmap = null;
    	}*/
        
        //2、zoom bmp
        Bitmap zoomBmp = zoomBitmap(newBmp, newBmp.getWidth() / scale, newBmp.getHeight() / scale);
        newBmp.recycle();
        newBmp = null;
        
    	Log.i(TAG, "zoomBmp.width = "+zoomBmp.getWidth()+" zoomBmp.getHeight = "+zoomBmp.getHeight());

        
        //3、初始化模糊参数
        init(zoomBmp);
                //4、模糊化
        process(9);
        
        Bitmap blurredBmp = returnBlurredImage();
        
       	Log.i(TAG, "blurredBmp.width = "+blurredBmp.getWidth()+" blurredBmp.getHeight = "+blurredBmp.getHeight());

        
        newBmp =zoomBitmap(blurredBmp, bgWidth, bgHeight);
       	Log.i(TAG, "newBmp.width = "+newBmp.getWidth()+" newBmp.getHeight = "+newBmp.getHeight());

        blurredBmp.recycle();
        blurredBmp = null;
        
        return newBmp;        
    }
	
	private float getDegreesForRotation(int value) {
        switch (value) {  
        case Surface.ROTATION_90:  
            return 360f - 90f;  
        case Surface.ROTATION_180:  
            return 360f - 180f;  
        case Surface.ROTATION_270:  
            return 360f - 270f;  
        }  
        return 0f;  
    }
		
	public void destroy(){
		if(_image != null){
			_image.recycle();
			_image = null;
		}
	}
	
}

模糊图片获取方法:
1、在窗口中导入类:import com.sios.view.StackBlurManager;
2、调用StackBlurManager(context)初始化该类,只需要初始化一次;
3、调用StackBlurManager类的成员函数GetBlurredBitmap获取模糊图片,函数中参数
bgWidth, bgHeight为获取图片的宽和高,scale为图片模糊化系数,使用系统默
认模糊画参数,
该值需要设置为-1;
4、当窗口退出时,调用destroy()函数释放资源;


使用参考代码:

StackBlurManager mStackBlurManager = new StackBlurManager(context);

     Bitmap blurredBmp =
mStackBlurManager.GetBlurredBitmap(controlWidth, controlHeight, -1);
     Bitmap newBmp = Bitmap.createBitmap(controlWidth, controlHeight,
Bitmap.Config.ARGB_8888);
     newBmp.setDensity(DisplayMetrics.DENSITY_DEVICE);
     Canvas canvas = new Canvas(newBmp);
     canvas.setDensity(DisplayMetrics.DENSITY_DEVICE);
         canvas.drawBitmap(blurredBmp, 0, 0, null);

         blurredBmp.recycle();
         blurredBmp = null;


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值