Hopefully we’re growing all the time ~
Look here ~
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'
- xml
<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>
借鉴文章