我们需要建立一个Drawable转化为Bitmap的工具类BlurredUtil
public class BlurredUtil { /** * 将Drawable对象转化为Bitmap对象 * * @param drawable Drawable对象 * @return 对应的Bitmap对象 */ static Bitmap drawableToBitmap(Drawable drawable) { Bitmap bitmap; if (drawable instanceof BitmapDrawable) { BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable; if (bitmapDrawable.getBitmap() != null) { return bitmapDrawable.getBitmap(); } } if (drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) { bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); // Single color bitmap will be created of 1x1 pixel } else { bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); } Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); drawable.draw(canvas); return bitmap; } }我们通过Android自带的ScriptIntrinsicBlur来实现模糊效果
public class BlurBitmap { /** * 图片缩放比例 */ private static final float BITMAP_SCALE = 0.4f; /** * 最大模糊度(在0.0到25.0之间) */ private static final float BLUR_RADIUS = 25f; /** * 模糊图片的具体方法 * * @param context 上下文对象 * @param image 需要模糊的图片 * @return 模糊处理后的图片 */ static Bitmap blur(Context context, Bitmap image) { // 计算图片缩小后的长宽 int width = Math.round(image.getWidth() * BITMAP_SCALE); int height = Math.round(image.getHeight() * BITMAP_SCALE); // 将缩小后的图片做为预渲染的图片。 Bitmap inputBitmap = Bitmap.createScaledBitmap(image, width, height, false); // 创建一张渲染后的输出图片。 Bitmap outputBitmap = Bitmap.createBitmap(inputBitmap); // 创建RenderScript内核对象 RenderScript rs = RenderScript.create(context); // 创建一个模糊效果的RenderScript的工具对象 ScriptIntrinsicBlur blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)); // 由于RenderScript并没有使用VM来分配内存,所以需要使用Allocation类来创建和分配内存空间。 // 创建Allocation对象的时候其实内存是空的,需要使用copyTo()将数据填充进去。 Allocation tmpIn = Allocation.createFromBitmap(rs, inputBitmap); Allocation tmpOut = Allocation.createFromBitmap(rs, outputBitmap); // 设置渲染的模糊程度, 25f是最大模糊度 blurScript.setRadius(BLUR_RADIUS); // 设置blurScript对象的输入内存 blurScript.setInput(tmpIn); // 将输出数据保存到输出内存中 blurScript.forEach(tmpOut); // 将数据填充到Allocation中 tmpOut.copyTo(outputBitmap); return outputBitmap; } }实现我们模糊的自定义控件,集成及RelativeLayout
public class BlurredView extends RelativeLayout { /** * 模糊最大化值 */ private static final int ALPHA_MAX_VALUE = 255; /** * Context */ private Context mContext; /** * 模糊后的ImageView */ private ImageView mBlurredImg; /** * 原图ImageView */ private ImageView mOriginImg; /** * 原图Bitmap */ private Bitmap mOriginBitmap; /** * 模糊后的Bitmap */ private Bitmap mBlurredBitmap; /** * 是否禁用模糊效果 */ private boolean isDisableBlurred; /** * 是否移动背景图片 */ private boolean isMove; public BlurredView(Context context) { super(context); init(context); } public BlurredView(Context context, AttributeSet attrs) { super(context, attrs); init(context); initAttr(context, attrs); } public BlurredView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context); initAttr(context, attrs); } private void init(Context context) { mContext = context; LayoutInflater.from(context).inflate(R.layout.blurredview, this); mOriginImg = (ImageView) findViewById(R.id.blurredview_origin_img); mBlurredImg = (ImageView) findViewById(R.id.blurredview_blurred_img); } private void initAttr(Context context, AttributeSet attrs) { TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.BlurredView); Drawable drawable = typedArray.getDrawable(R.styleable.BlurredView_src); isMove = typedArray.getBoolean(R.styleable.BlurredView_move, false); isDisableBlurred = typedArray.getBoolean(R.styleable.BlurredView_disableBlurred, false); typedArray.recycle(); // blur image if (null != drawable) { mOriginBitmap = BlurredUtil.drawableToBitmap(drawable); mBlurredBitmap = BlurBitmap.blur(context, mOriginBitmap); } // setVisibility if (!isDisableBlurred) { mBlurredImg.setVisibility(VISIBLE); } // setMove if (null != drawable) { setMove(context, isMove); } } /** * 设置背景图片移动效果 * * @param context 上下文对象 * @param isMove 是否移动 */ private void setMove(Context context, boolean isMove) { if (isMove) { WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); Display display = wm.getDefaultDisplay(); Point point = new Point(); display.getSize(point); int height = point.y; setBlurredHeight(height, mOriginImg); setBlurredHeight(height, mBlurredImg); } } /** * 改变图片的高度 * * @param height 图片的高度 * @param imageView imageview对象 */ private void setBlurredHeight(int height, ImageView imageView) { ViewGroup.LayoutParams params = imageView.getLayoutParams(); params.width = ViewGroup.LayoutParams.MATCH_PARENT; params.height = height + 100; imageView.requestLayout(); } @Override protected void onFinishInflate() { super.onFinishInflate(); setImageView(); } /** * 填充ImageView. */ private void setImageView() { mBlurredImg.setImageBitmap(mBlurredBitmap); mOriginImg.setImageBitmap(mOriginBitmap); } /** * 以代码的方式添加待模糊的图片 * * @param blurredBitmap 待模糊的图片 */ public void setBlurredImg(Bitmap blurredBitmap) { if (null != blurredBitmap) { mOriginBitmap = blurredBitmap; mBlurredBitmap = BlurBitmap.blur(mContext, blurredBitmap); setImageView(); setMove(mContext, isMove); } } /** * 以代码的方式添加待模糊的图片 * * @param blurDrawable 待模糊的图片 */ public void setBlurredImg(Drawable blurDrawable) { if (null != blurDrawable) { mOriginBitmap = BlurredUtil.drawableToBitmap(blurDrawable); mBlurredBitmap = BlurBitmap.blur(mContext, mOriginBitmap); setImageView(); setMove(mContext, isMove); } } /** * 设置模糊程度 * * @param level 模糊程度, 数值在 0~100 之间. */ public void setBlurredLevel(int level) { if (level < 0 || level > 100) { throw new IllegalStateException("No validate level, the value must be 0~100"); } if (isDisableBlurred) { return; } mOriginImg.setAlpha((int) (ALPHA_MAX_VALUE - level * 2.55)); } /** * 设置图片上移的距离 * * @param hight 向上移动的距离 */ public void setBlurredTop(int hight) { mOriginImg.setTop(-hight); mBlurredImg.setTop(-hight); } /** * 显示模糊图片 */ public void showBlurredView() { mBlurredImg.setVisibility(VISIBLE); } /** * 禁用模糊效果 */ public void disableBlurredView() { isDisableBlurred = true; mOriginImg.setAlpha(ALPHA_MAX_VALUE); mBlurredImg.setVisibility(INVISIBLE); } /** * 启用模糊效果 */ public void enableBlurredView() { isDisableBlurred = false; mBlurredImg.setVisibility(VISIBLE); } }对应的xml文件为
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/blurredview_blurred_img" android:scaleType="fitXY" android:visibility="gone" android:layout_width="match_parent" android:layout_height="match_parent"/> <ImageView android:id="@+id/blurredview_origin_img" android:scaleType="fitXY" android:layout_width="match_parent" android:layout_height="match_parent"/> </FrameLayout>