相关文章推荐
温暖的电梯  ·  Android 背景模糊处理 ...·  8 月前    · 
闯红灯的牛肉面  ·  高斯模糊 - 知乎·  11 月前    · 
行走的吐司  ·  swift动画 —— ...·  1 年前    · 
文质彬彬的热带鱼  ·  MQTT(EMQX) - ...·  4 周前    · 
慈祥的萝卜  ·  vue3 ...·  6 月前    · 

Android 动态毛玻璃背景的简单实现(高斯模糊)

做APP的时候,UI总是会搞一些这种高斯模糊的效果,为了方便使用,简单讲一下怎么实现,以及提供封装好的View。
我这里是采用RenderScript来实现的高斯模糊,RenderScript 是用于在 Android 上以高性能运行计算密集型任务的框架,性能比较能满足需求。

大概效果如下,可以看一下是否满足你的需求

实现步骤大概可以分为三步

  1. 截取需要模糊的区域的背景
  2. 对截取到的bitmap进行高斯模糊处理
  3. 为ImageView设置Bitmap

先新建一个类BlurBGImageView继承自ImageView,然后一步步实现下面的方法,完整代码在文末

截取对应的背景图方法

*view 需要截取的背景View,在效果图中就是后面的recycleView private Bitmap getBitmap ( View view ) { //获取屏幕整张图片 Bitmap bitmap = view . getDrawingCache ( ) ; if ( bitmap != null ) { //需要截取的长和宽 int outWidth = this . getWidth ( ) ; int outHeight = this . getHeight ( ) ; //获取需要截图部分的在屏幕上的坐标(view的左上角坐标) int [ ] viewLocationArray = new int [ 2 ] ; this . getLocationOnScreen ( viewLocationArray ) ; //背景View所在屏幕上的坐标 int [ ] listLocationArray = new int [ 2 ] ; view . getLocationOnScreen ( listLocationArray ) ; //从屏幕整张图片中截取指定区域 bitmap = Bitmap . createBitmap ( bitmap , viewLocationArray [ 0 ] - listLocationArray [ 0 ] , viewLocationArray [ 1 ] - listLocationArray [ 1 ] , outWidth , outHeight ) ; return bitmap ;

对图片进行高斯模糊然后setImageBitmap设置

*radius 模糊半径 private void blur ( Bitmap bkg , ImageView view , float radius ) { if ( overlay != null ) { overlay . recycle ( ) ; //图片的大小很影响高斯模糊的速度,所以我们对图片先进行缩放,scaleFactor为缩放的倍数 overlay = Bitmap . createScaledBitmap ( bkg , bkg . getWidth ( ) / scaleFactor , bkg . getHeight ( ) / scaleFactor , false ) ; overlay = blur ( getContext ( ) , overlay , radius ) ; //高斯模糊 view . setImageBitmap ( overlay ) ; private Bitmap blur ( Context context , Bitmap image , float radius ) { RenderScript rs = RenderScript . create ( context ) ; Bitmap outputBitmap = Bitmap . createBitmap ( image . getWidth ( ) , image . getHeight ( ) , Bitmap . Config . ARGB_8888 ) ; Allocation in = Allocation . createFromBitmap ( rs , image ) ; Allocation out = Allocation . createFromBitmap ( rs , outputBitmap ) ; ScriptIntrinsicBlur intrinsicBlur = ScriptIntrinsicBlur . create ( rs , Element . U8_4 ( rs ) ) ; intrinsicBlur . setRadius ( radius ) ; intrinsicBlur . setInput ( in ) ; intrinsicBlur . forEach ( out ) ; out . copyTo ( outputBitmap ) ; image . recycle ( ) ; rs . destroy ( ) ; return outputBitmap ;

好了,最后我们再对外开放一个方法,供外部调用就可以了

*bgView 从外部传入的背景View public void refreshBG ( View bgView ) { bgView . setDrawingCacheEnabled ( true ) ; bgView . buildDrawingCache ( ) ; Bitmap bitmap1 = null ; try { bitmap1 = getBitmap ( bgView ) ; } catch ( Exception e ) { e . printStackTrace ( ) ; if ( bitmap1 != null ) { blur ( bitmap1 , this , radius ) ; //模糊处理 bitmap1 . recycle ( ) ; bgView . setDrawingCacheEnabled ( false ) ; //清除缓存

XML处调用

    <com.lpoint.widget.BlurBGImageView
        android:id="@+id/img_vague"
        android:layout_width="300dp"
        android:layout_centerInParent="true"
        android:layout_height="200dp"/>
 

完整的BlurBGImageView类

import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Bitmap; import android.renderscript.Allocation; import android.renderscript.Element; import android.renderscript.RenderScript; import android.renderscript.ScriptIntrinsicBlur; import android.util.AttributeSet; import android.view.View; import android.widget.ImageView; import androidx.annotation.Nullable; @SuppressLint("AppCompatCustomView") public class BlurBGImageView extends ImageView { Bitmap overlay; int scaleFactor = 2; int radius = 8; public BlurBGImageView(Context context) { super(context); public BlurBGImageView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); public BlurBGImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); public void setScaleFactor(int scaleFactor) { this.scaleFactor = scaleFactor; public void refreshBG(View bgView){ bgView.setDrawingCacheEnabled(true); bgView.buildDrawingCache(); Bitmap bitmap1 = null; try { bitmap1 = getBitmap(bgView); } catch (Exception e) { e.printStackTrace(); if (bitmap1 != null){ blur(bitmap1,this,radius);//模糊处理 bitmap1.recycle(); bgView.setDrawingCacheEnabled(false);//清除缓存 private void blur(Bitmap bkg, ImageView view, float radius) { if (overlay != null){ overlay.recycle(); overlay = Bitmap.createScaledBitmap(bkg, bkg.getWidth() / scaleFactor, bkg.getHeight() / scaleFactor, false); overlay = blur(getContext(),overlay, radius);//高斯模糊 view.setImageBitmap(overlay); private Bitmap blur(Context context, Bitmap image, float radius) { RenderScript rs = RenderScript.create(context); Bitmap outputBitmap = Bitmap.createBitmap(image.getWidth(), image.getHeight(), Bitmap.Config.ARGB_8888); Allocation in = Allocation.createFromBitmap(rs, image); Allocation out = Allocation.createFromBitmap(rs, outputBitmap); ScriptIntrinsicBlur intrinsicBlur = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)); intrinsicBlur.setRadius(radius); intrinsicBlur.setInput(in); intrinsicBlur.forEach(out); out.copyTo(outputBitmap); image.recycle(); rs.destroy(); return outputBitmap; private Bitmap getBitmap(View view){ //获取屏幕整张图片 Bitmap bitmap = view.getDrawingCache(); if (bitmap != null) { //需要截取的长和宽 int outWidth = this.getWidth(); int outHeight = this.getHeight(); //获取需要截图部分的在屏幕上的坐标(view的左上角坐标) int[] viewLocationArray = new int[2]; this.getLocationOnScreen(viewLocationArray); int[] listLocationArray = new int[2]; view.getLocationOnScreen(listLocationArray); //从屏幕整张图片中截取指定区域 bitmap = Bitmap.createBitmap(bitmap, viewLocationArray[0] - listLocationArray[0], viewLocationArray[1] - listLocationArray[1], outWidth, outHeight); return bitmap;

最后在Activity里面调用(建议调用间隔不小于30ms)

imgVague.refreshBG(recyclerView);
仔细观察上图,我们可以发现,背景图以用户头像为模板,对其进行了高斯模糊,并把它作为整个页面的背景色。
关于Android如何快速实现高斯模糊毛玻璃效果),网上一堆相关介绍,可参考下面文章一种快速毛玻璃虚化效果实现Android。 下面直接给出模糊化工具类(已验证可行):
import android.graphics.Bitmap;
* 快速模糊化工具
public class FastBlur {
public static Bitm
                                    自从iOS系统引入了Blur效果,也就是所谓的毛玻璃、模糊化效果、磨砂效果,各大系统就开始竞相模仿,这是怎样的一个效果呢,我们先来看一下,如下面的图片:
实现效果大家都知道了,如何在Android实现呢,说白了就是对图片进行模糊化处理,小编先给大家讲一下Android高级模糊技术的原理,如下:
  首先我创建了一个空的bitmap,把背景的一部分复制进去,之后我会对这个bitmap进行模糊处理并设置为TextView的背景。
  通过这个bitmap保存Canvas的状态;
  在父布局文件中把Canvas移动到TextView的位置;
  把ImageView的内容绘到bitmap中;
                                    0. 前言在Android开发中,经常在音乐软件中看到高斯模糊效果。在找遍了所有高斯模糊的算法代码后,发现stackblur的Java实现是最快的。效果如下所示。1.高斯模糊效果实现Bitmap overlay;
JavaBlurProcess process = new JavaBlurProcess();
private void blur(Bitmap srcBitmap, Imag...
将View转成Bitmap,并且记录列表的滑动距离,生成bitmap时上移画布(这样是为了实现滑到那,模糊那的效果)
上移画布:一般绘制View,canvas的起始点在屏幕的左上角,也就是(0,0)。当canvas上移距离y后,绘制的起点会变成(0,-y)。这样canvas竖直方向-y到0这一部分会在屏幕外,那么在绘制的时候view的top到top+y是在屏幕外面,我们看不到;我们能看到的
                                    最近做项目有这样的需求: 在activity中启动一个dialog时, 启动的dialog的背景设为启动acitivity的模糊化图片.实现思路: 
1. 截屏, 获取当前activity的界面 
2. 将获取的照片进行模糊化 
3. 将模糊化的图片设为dialog的背景1.截屏, 获取当前activity的界面    private Bitmap takeScreenShot(Activity a
                                    项目需要做一个半透明的高斯模糊,用来覆盖下面的布局,样式类似下面这种image.png所以第一时间想到了高斯模糊来做。半透明的高斯模糊其实不难实现,只需要知道android.support.v8.renderscript这个包基本上就可以实现了。使用之前可以先看看 https://www.jianshu.com/p/dd0a339e288epublic class BlurringView ext...
                                    在现在好多背景图片都流行用高斯模糊图片做背景,比如音乐播放器页面,SystemUI下拉状态栏背景 好多都流行高斯模糊
高斯模糊的几种实现方式:
(1)RenderScript
RenderScript是Google在Android 3.0(API 11)中引入的一个高性能图片处理框架。
使用RenderScriprt实现高斯模糊:
(2) 使用Glide实现高斯模糊
第一种RenderScipt实现高斯模糊
public Bitmap blurBitmap(Context context, Bitmap b
二、实现步骤
1、在armeabi-v7a文件夹下添加两个库文件(librsjni.so,libRSSupport.so)以及在libs文件夹下添加一个架包renderscript-v8.jar。
下载地址:
2、在菜单界面(这里是popuwindow菜单界面)加载时,通过预览对菜单底部当前Activity显示的View保存成Bitma
                                    在找遍了网上所有关于实时高斯模糊的效果,并没有直接现成的例子,所以自己东拼西凑,在加上自己的改动,终于实现出来了 
本示例是在ConvenientBanner这个开源库demo上改的,自己写一个浪费时间,直接拿来用在找遍了所有高斯模糊的算法代码后,发现stackblur的java实现是最快的先说一下大致思路,非常简单。模糊的区域其实是一张Imageview,当视图发生变化,在滚动的时候,截
                                    Android 弹窗毛玻璃背景实践需求: 点击FloatingActionButton弹出弹层,弹层底部有多个图标可选,每一个图标都是一个功能入口,背景采用毛玻璃模糊效果。记录一下这个需求的思考和实现过程。查找Android原生API做法在Android API里面,有个FLAG_BLUR_BEHIND用于模糊背景的FLAG,尝试一下使用它来做Dialog的背景模糊。 代码如下:final Dia...