blurkit三方框架

记得去年做项目的时候,有涉及到毛玻璃遮罩层的功能,但是因为项目时间太紧,所以放弃了毛玻璃的效果,索性最近有时间就学习记录一波 ~ 文中细节并没有去处理,只是用最简单的方式,实现了我的需求 ~

半成品 - Demo 效果
注 :个人感觉,更适合整体遮罩层

要实现效果可直接跳到使用方式开始看!

关于更具体的详情,请查看文末的借鉴文章之处 > <~

1.Java实现,一般都是采用Stack模糊算法 (亲测:频繁invalidate(),模糊效果消失)
2.RenderScript实现 (亲测:频繁invalidate(),模糊效果消失)
3.Native实现 (未尝试)
4.OpenCV或者OpenGL实现(未尝试)

  • BlurLayout自定义属性
  • 注:只用到了blurkit:blk_fps属性,其他属性一用就报错,崩溃的那种,具体问题没有去排查,因为懒 ~

    看别人的博客也存在这样的问题,原话是这样的:在blurkit-android的目前的代码中(包括最新版本),BlurLayout的blk_alpha属性并不能使用。因为在代码中存在类型转换错误。英语好的同学可以去提issue

    当然他说的是blk_alpha属性 - - 有机会我在重新尝试

        //每过1000/fps的时间重新绘制一次BlurLayout,
        blurkit:blk_fps="60"
        //透明度
        blurkit:blk_alpha="0.5"
        //模糊半径
        blurkit:blk_blurRadius="15"
        //BlurLayout的圆角半径
        blurkit:blk_cornerRadius="30dp"
        //缩放大小,是先放大再缩小,所以值太大则有可能OOM
        blurkit:blk_downscaleFactor="0.12"
    
  • 直接对View及Bitmap进行高斯模糊的使用(测量TextView会崩溃,提示宽高测不到,为0)
  •   //进行BlurKit初始化,在Application中初始化
      BlurKit.init(this);
      //通过RenderScript进行高斯模糊并返回一个bitmap,iv1可以是一个View,也可以是一个ViewGroup,25是模糊半径
      Bitmap bt=BlurKit.getInstance().blur(iv1, 25);
      //通过RenderScript进行高斯模糊并返回一个bitmap,传入的是一个bitmap,25是模糊半径
      Bitmap bt=BlurKit.getInstance().blur(bitmap, 25);
      //通过RenderScript进行高斯模糊并返回一个bitmap,iv1可以是一个View,也可以是一个ViewGroup,25是模糊半径,2代表缩放比例,如果值太大可能会出现OOM
      Bitmap bt=BlurKit.getInstance().fastBlur(iv1,25,2)
    
  • blurkit-android的毛玻璃实现原理(Me no look)
  •   //在类BlurKit中
      public Bitmap blur(Bitmap src, int radius) {
          final Allocation input = Allocation.createFromBitmap(rs, src);
          final Allocation output = Allocation.createTyped(rs, input.getType());
          final ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
          script.setRadius(radius);
          script.setInput(input);
          script.forEach(output);
          output.copyTo(src);
          return src;
    
  • bulid.app
  • 注 :要使用blurkit-android的1.1.1版本(目前最新版本),不要使用1.1.0版本(虽然GitHub上的使用文档还是1.1.0)
    因为使用1.1.1版本时minSdkVersion的值可以是17,而使用1.1.0版本时minSdkVersion的值必须是21

      implementation 'io.alterac.blurkit:blurkit:1.1.1'
    
        <io.alterac.blurkit.BlurLayout
            android:id="@+id/blurLayout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="center"
            blurkit:blk_fps="0"/>
    
  • Activity、Fragment等使用处
  •   @Override
      protected void onStart() {
          super.onStart();
          blurLayout.startBlur();
          blurLayout.lockView();
      @Override
      protected void onStop() {
          super.onStop();
          blurLayout.pauseBlur();
    
  • MainActivity
  • package nkwl.com.glassdemo;
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.view.View;
    import android.widget.TextView;
    import android.widget.Toast;
    import io.alterac.blurkit.BlurLayout;
    public class MainActivity extends AppCompatActivity {
        private BlurLayout blurLayout;
        private TextView mStart;
        private TextView mStop;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            mStart = findViewById(R.id.tv_start);
            mStop = findViewById(R.id.tv_stop);
            blurLayout = findViewById(R.id.blurLayout);
            mStart.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Toast.makeText(MainActivity.this, "开始模糊", Toast.LENGTH_LONG).show();
                    blurLayout.setVisibility(View.VISIBLE);
            mStop.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Toast.makeText(MainActivity.this, "停止模糊", Toast.LENGTH_LONG).show();
                    blurLayout.setVisibility(View.GONE);
        @Override
        protected void onStart() {
            super.onStart();
            blurLayout.startBlur();
            blurLayout.lockView();
        @Override
        protected void onStop() {
            super.onStop();
            blurLayout.pauseBlur();
    
  • activity_main
  • <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:blurkit="http://schemas.android.com/apk/res-auto"
        android:id="@+id/ll_parent"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@mipmap/bg"
        android:orientation="vertical">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="45dp"
            android:orientation="horizontal">
            <TextView
                android:id="@+id/tv_start"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:gravity="center"
                android:text="开始模糊" />
            <TextView
                android:id="@+id/tv_stop"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:gravity="center"
                android:text="停止模糊" />
        </LinearLayout>
        <io.alterac.blurkit.BlurLayout
            android:id="@+id/blurLayout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="center"
            android:visibility="gone"
            blurkit:blk_fps="0">
            <TextView
                android:layout_width="match_parent"
                android:layout_height="100dp"
                android:layout_marginTop="266dp"
                android:background="#fff"
                android:gravity="center"
                android:text="开始的开始,我们只是孩子"
                android:textColor="#f96" />
        </io.alterac.blurkit.BlurLayout>
    </LinearLayout>
    

    blurry三方框架

    半成品 - Demo 效果 (模糊效果有点丑 - -)

    注 :个人感觉,更适合单一控件

     //for ViewGroup 亲测无效,可能是个人原因
      Blurry.with(context)
        .radius(10)//模糊半径
        .sampling(8)//缩放大小,先缩小再放大
        .color(Color.argb(66, 255, 255, 0))//颜色
        .async()//是否异步
        .animate(500)//显示动画,目前仅支持淡入淡出,默认时间是300毫秒,仅支持传入控件为ViewGroup
        .onto(viewGroup);
      //for view
      Blurry.with(context) 亲测无效,可能是个人原因
        .radius(10)//模糊半径
        .sampling(8)//缩放大小,先缩小再放大
        .color(Color.argb(66, 255, 255, 0))//颜色
        .async()//是否异步
        .capture(view)//传入View
        .into(view);//显示View
      //for bitmap 亲测有效
      Blurry.with(context)
        .radius(10)//模糊半径
        .sampling(8)//缩放大小,先缩小再放大
        .color(Color.argb(66, 255, 255, 0))//颜色
        .async()//是否异步
        .from(bitmap)//传入bitmap
        .into(view);//显示View
    

    注:只实现了第三种使用方法

  • build.app
  •  implementation 'jp.wasabeef:blurry:3.0.0'
    
  • MainActivity
  • package nkwl.com.glassdemo;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.Color;
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.view.View;
    import android.widget.ImageView;
    import android.widget.Toast;
    import jp.wasabeef.blurry.Blurry;
    public class MainActivity extends AppCompatActivity {
        private ImageView mAlineView;
        private Bitmap bitmap;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            mAlineView = findViewById(R.id.tv_aline_view);
            //本地图片转为bitmap进行数据传入
            bitmap = BitmapFactory.decodeResource(this.getResources(), R.mipmap.bg);
            findViewById(R.id.tv_start).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Toast.makeText(MainActivity.this, "开始模糊", Toast.LENGTH_LONG).show();
                    Blurry.with(MainActivity.this)
                            .radius(10)//模糊半径
                            .sampling(8)//缩放大小,先缩小再放大
                            .color(Color.argb(66, 255, 255, 0))//颜色
                            .async()//是否异步
                            .from(bitmap)//传入View
                            .into(mAlineView);//显示View
            findViewById(R.id.tv_stop).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Toast.makeText(MainActivity.this, "停止模糊", Toast.LENGTH_LONG).show();
                    Blurry.with(MainActivity.this)
                            .radius(10)//模糊半径
                            .sampling(8)//缩放大小,先缩小再放大
                            .color(Color.argb(0, 0, 0, 0))//颜色
                            .async()//是否异步
                            .from(bitmap)//传入View
                            .into(mAlineView);//显示View
    
  • activity_main
  • <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@mipmap/bg"
        android:orientation="vertical">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="45dp"
            android:orientation="horizontal">
            <TextView
                android:id="@+id/tv_start"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:gravity="center"
                android:text="开始模糊" />
            <TextView
                android:id="@+id/tv_stop"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:gravity="center"
                android:text="停止模糊" />
        </LinearLayout>
        <ImageView
            android:id="@+id/tv_aline_view"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:layout_marginTop="266dp"
            android:contentDescription="@null"
            android:gravity="center"
            android:scaleType="fitXY"
            android:src="@drawable/bg"
            android:visibility="visible" />
    </LinearLayout>
    
  • 玉刚说推荐 - 毛玻璃效果在Android的实现
  • 原作者项目github地址 - blurkit-android
  •