Android源码中添加高斯模糊背景-毛玻璃
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Android源码中添加高斯模糊背景-毛玻璃,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含7633字,纯文字阅读大概需要11分钟。
内容图文
![Android源码中添加高斯模糊背景-毛玻璃](/upload/InfoBanner/zyjiaocheng/782/0944c89f859f4a3c94ac10a62d1fbfc3.jpg)
不积跬步无以至千里
由于系统中多处使用了高斯模糊处理的背景效果,这里感觉也算一个有b格的设计,因此把实现记录下来,而且多数的处理是基于上层的添加方式,这里说一下源码下的整个流程.
1.配置Android.mk
配置其中所需要的库,以及RenderScript所依赖的环境
LOCAL_STATIC_JAVA_LIBRARIES += android-support-v8-renderscript
LOCAL_RENDERSCRIPT_TARGET_API := 18
LOCAL_RENDERSCRIPT_COMPATIBILITY := 18
LOCAL_RENDERSCRIPT_FLAGS := -rs-package-name=android.support.v8.renderscript
LOCAL_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源码中添加高斯模糊背景-毛玻璃所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。