不积跬步无以至千里
由于系统中多处使用了高斯模糊处理的背景效果,这里感觉也算一个有b格的设计,因此把实现记录下来,而且多数的处理是基于上层的添加方式,这里说一下源码下的整个流程.
1.配置AndroID.mk
配置其中所需要的库,以及RenderScript所依赖的环境
LOCAL_STATIC_JAVA_liBRARIES += androID-support-v8-renderscriptLOCAL_RENDERSCRIPT_TARGET_API := 18LOCAL_RENDERSCRIPT_COMPATIBIliTY := 18LOCAL_RENDERSCRIPT_FLAGS := -rs-package-name=androID.support.v8.renderscriptLOCAL_JNI_SHARED_liBRARIES := librsjni
2.复制此高斯模糊处理的类
package com.androID.server.utils;import androID.content.Context;import androID.graphics.Bitmap;import androID.graphics.Canvas;import androID.graphics.Paint;import androID.graphics.PorterDuff;import androID.graphics.PorterDuffXfermode;import androID.graphics.Rect;import androID.graphics.drawable.Drawable;import androID.support.v8.renderscript.Allocation;import androID.support.v8.renderscript.Element;import androID.support.v8.renderscript.RenderScript;import androID.support.v8.renderscript.ScriptIntrinsicBlur;import androID.util.displayMetrics;import androID.util.Log;import androID.vIEw.display;import androID.vIEw.Surface;import androID.vIEw.SurfaceControl;import androID.vIEw.WindowManager;/** * Created by wangdy on 2019-02-18. */public class VargoBlurBackground { private static final int SCALE = 2; private static VargoBlurBackground mInstance; private Context mContext; private Bitmap mBlurBitmap; private Paint mPaint; private boolean mShooting = false; private boolean mNeedUpdate = false; private boolean mDoNotUpdate = false; public static VargoBlurBackground getInstance() { return mInstance; } private String Tags="VargoBlurBackground"; public static voID Init(Context ctx) { if(mInstance == null) { mInstance = new VargoBlurBackground(ctx); } } public VargoBlurBackground(Context mContext) { this.mContext = mContext.getApplicationContext(); } public voID skipOnceScreenShot() { mDoNotUpdate = true; } public voID updateScreenShot() { if(mDoNotUpdate) { mDoNotUpdate = false; return ; } if(mBlurBitmap != null && !mNeedUpdate) return ; mShooting = true; try { if(mBlurBitmap != null && !mBlurBitmap.isRecycled()) { mBlurBitmap.recycle(); } Bitmap b = takeScreenShot(); if(b == null) { return ; } mBlurBitmap = createBlurredImage(b, 25); b.recycle(); } finally { mNeedUpdate = false; mShooting = false; } } public voID forceUpdate() { mNeedUpdate = true; } public voID releaseBlur() { if(mBlurBitmap != null && !mBlurBitmap.isRecycled()) { mBlurBitmap.recycle(); } } public voID draw(Canvas canvas, int left, int top, int right, int bottom, Drawable mask) { if(mBlurBitmap == null || mBlurBitmap.isRecycled()) { return ; } if(mShooting) { return ; } if(mPaint == null) { mPaint = new Paint(); mPaint.setAntiAlias(true); } Rect source = new Rect(left, top, right, bottom); //Log.e(Tags,"draw:source="+source.toString()); Rect blur = new Rect(0, 0, mBlurBitmap.getWIDth()<<SCALE, mBlurBitmap.getHeight()<<SCALE); Rect intersec = new Rect(); //计算交集 if (!intersec.setIntersect(source, blur)) { //两个矩形,不相交,不绘制 return ; } //计算要绘制的Blur区域 int l = intersec.left >> SCALE; int t = intersec.top >> SCALE; int r = intersec.right >> SCALE; int b = intersec.bottom >> SCALE; Rect src = new Rect(l, t, r, b); //Log.e(Tags,"draw:src="+src.toString()); //计算要复制到的区域 Rect target = new Rect(); target.left = intersec.left - source.left; target.top = intersec.top - source.top; target.right = target.left + intersec.wIDth(); target.bottom = target.top + bottom; //Log.e(Tags,"draw:target="+target.toString()); canvas.save(); //绘制Mask/* if(mask != null) { mask.setBounds(target); mask.draw(canvas); }*/ mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); canvas.drawBitmap(mBlurBitmap, src, target, mPaint); mPaint.reset(); canvas.restore(); } private Bitmap createBlurredImage (Bitmap orginal, int radius) { Bitmap blurredBitmap; blurredBitmap = Bitmap.createBitmap(orginal); // Create the Renderscript instance that will do the work. RenderScript rs = RenderScript.create(mContext); // Allocate memory for Renderscript to work with Allocation input = Allocation.createFromBitmap(rs, orginal, Allocation.MipmapControl.MIPMAP_FulL, Allocation.USAGE_SCRIPT); Allocation output = Allocation.createTyped(rs, input.getType()); // Load up an instance of the specific script that we want to use. ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)); script.setinput(input); // Set the blur radius script.seTradius(radius); // Start the ScriptIntrinisicBlur script.forEach(output); // copy the output to the blurred bitmap output.copyTo(blurredBitmap); input.destroy(); output.destroy(); rs.destroy(); Paint p = new Paint(); Canvas c = new Canvas(blurredBitmap); p.setStyle(Paint.Style.FILL); //vg:wangdy modify from 0x66281f1d to 0x99000000_2019-02-18 p.setcolor(0x99000000); c.drawRect(new Rect(0, 0, blurredBitmap.getWIDth(), blurredBitmap.getHeight()), p); p = null; c = null; return blurredBitmap; } public Bitmap takeScreenShot(){ WindowManager mWindowManager; displayMetrics mdisplayMetrics; display mdisplay; mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); mdisplay = mWindowManager.getDefaultdisplay(); mdisplayMetrics = new displayMetrics(); mdisplay.getRealMetrics(mdisplayMetrics); int wIDth = (int)mdisplayMetrics.wIDthPixels; int height =(int)mdisplayMetrics.heightPixels; int layer = 3 * 10000+1000; Bitmap screenBitmap = SurfaceControl.screenshot(new Rect(), wIDth, height, 0, layer, false, Surface.ROTATION_0); if(screenBitmap == null){ return null; } Bitmap ret = Bitmap.createScaledBitmap(screenBitmap, wIDth>>SCALE, height>>SCALE, false); screenBitmap.recycle(); return ret; } }
这里就是整体的高斯模糊处理,提供接口供使用.
3.在需要高斯模糊处理的布局需要自定义布局
如下代码
package com.androID.server.am;import androID.content.Context;import androID.graphics.Canvas;import androID.util.AttributeSet;import androID.Widget.relativeLayout;import com.androID.server.utils.VargoBlurBackground;/** * Created by wangdy add for user switch dialog's blur show on 2019-02-18. */public class VgUserSwitchingDialogrelativeLayout extends relativeLayout { public VgUserSwitchingDialogrelativeLayout(Context context) { this(context, null); } public VgUserSwitchingDialogrelativeLayout(Context context, AttributeSet attrs) { super(context, attrs, 0); } public VgUserSwitchingDialogrelativeLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @OverrIDe protected voID dispatchDraw(Canvas canvas) { final int[] location = new int[4]; getLocationOnScreen(location); location[2] = location[0] + getMeasureDWIDth(); location[3] = location[1] + getMeasuredHeight(); if (VargoBlurBackground.getInstance() != null) { VargoBlurBackground.getInstance().draw(canvas, location[0], location[1], location[2], location[3], getBackground()); } invalIDate(); super.dispatchDraw(canvas); }}
其中主要的是需要毛玻璃处理的这个布局自定义一下来实现这个dispatchDraw方法,来进行毛玻璃进行画布draw截取的bitmap.
4.需要在你使用的整体逻辑中初始化
如果是Activity就在onCreate,如果Fragment就在onCreateVIEw中,即初始化的时候进行初始化,由于我这里是Dialog在构造函数中初始化的
VargoBlurBackground.Init(this.getContext().getApplicationContext());
5.在触发显示布局的时候进行截图去刷新布局显示毛玻璃
如果你是滑动布局,会滑动开始显示布局的监听中去进行,我这里是AlertDialog,这里就在show方法中进行如下:
VargoBlurBackground.getInstance().updateScreenShot();VargoBlurBackground.getInstance().forceUpdate();
Over.
如果你需要调节毛玻璃的透明度与颜色就在上边所说的高斯模糊处理类(VargoBlurBackground)中的createBlurredImage方法中有
对这里进行Paint.setcolor的方法就是设置毛玻璃效果的透明度以及色彩的,上一篇文章已经提及了怎么修改这个值来修改其中的透明度与色值.
总结以上是内存溢出为你收集整理的Android源码中添加高斯模糊背景-毛玻璃全部内容,希望文章能够帮你解决Android源码中添加高斯模糊背景-毛玻璃所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)