什么是Filter
Filter中文名为滤镜,是图像处理领域的专业术语,统指各种用来实现图像特效的技术
Android中常用的特效包括两种,一种是蒙板滤镜MaskFilter,一种是色彩滤镜ColorFilter
MaskFilter工作原理
MaskFilter在绘制时,通过对Paint边缘像素的alpha通道进行变换,来实现模糊化或立体化等效果
Android内置的MaskFilter实现类有两个
一个是BlurMaskFilter,用于实现模糊效果
一个是EmbossMaskFilter,用于实现浮雕效果
ColorFilter工作原理
MaskFilter在绘制时,会对Paint的像素进行色彩值变换运算,从而实现各式各样的变色效果
比如色彩加深,灰度,底片,复古等效果
Android内置的ColorFilter实现类有LightingColorFilter,BlendModeColorFilter,PorterDuffColorFilter,ColorMatrixColorFilter等
它们通过不同的变换公式,来实现不同的变色效果
ColorMatrixColorFilter工作原理
ColorMatrixColorFilter通过定义一个变换矩阵,将初始的[R, G, B, A]像素,转换为新的像素[TR, TG, TB, TA]
变换矩阵的格式和计算公式如下
ColorMatrix matrix = new ColorMatrix([
a, b, c, d, e,
f, g, h, i, j,
k, l, m, n, o,
p, q, r, s, t
]);
int TR = a*R + b*G + c*B + d*A + e;
int TG = f*R + g*G + h*B + i*A + j;
int TB = k*R + l*G + m*B + n*A + o;
int TA = p*R + q*G + r*B + s*A + t;
Filter效果展示
核心代码
package com.android.architecture;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.MaskFilter;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;
//色彩滤镜效果
@SuppressWarnings("all")
public class ColorFilterView extends View {
Bitmap bitmap;
Paint paint;
public ColorFilterView(Context context) {
this(context, null);
}
public ColorFilterView(Context context, AttributeSet attributeSet) {
super(context, null);
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.de_ma);
paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.RED);
}
//使用MaskFilter时必须关闭硬件加速
public void setFilters(ColorFilter colorFilter, MaskFilter maskFilter) {
if (maskFilter != null)
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
paint.setColorFilter(colorFilter);
paint.setMaskFilter(maskFilter);
}
@Override
protected void onDraw(Canvas canvas) {
//画原图
Rect rect1 = new Rect(200, 200, 464, 464);
canvas.drawBitmap(bitmap, null, rect1, null);
//画带滤镜效果的图片
Rect rect2 = new Rect(200, 600, 464, 864);
canvas.drawBitmap(bitmap, null, rect2, paint);
}
}
package com.android.architecture;
import android.graphics.BlurMaskFilter;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.EmbossMaskFilter;
import android.widget.FrameLayout;
import com.easing.commons.android.app.CommonActivity;
import com.easing.commons.android.manager.Permissions;
import com.easing.commons.android.ui.control.title_bar.TitleBar;
import com.easing.commons.android.ui.dialog.BottomSlideDialog;
import com.easing.commons.android.view.Views;
import butterknife.BindView;
import lombok.SneakyThrows;
@SuppressWarnings("all")
public class StartActivity extends CommonActivity {
@BindView(R.id.titleBar)
TitleBar titleBar;
@BindView(R.id.container)
FrameLayout container;
BottomSlideDialog dialog;
@Override
protected boolean beforeCreate() {
statusBarColor = R.color.color_transparent;
navigationBarColor = R.color.color_light_blue;
return super.beforeCreate();
}
@Override
@SneakyThrows
protected void create() {
setContentView(R.layout.activity_start);
titleBar.showReturnButton(false);
titleBar.setBackgroundResource(R.drawable.color_light_blue);
titleBar.setTitleText("Filter");
requestPermission(Permissions.STORAGE);
dialog = BottomSlideDialog.create(ctx, R.layout.dialog_menu);
onClick(container, dialog::show);
init();
}
protected void init() {
//BlurMaskFilter实现模糊效果
dialog.onClick(R.id.menu1, () -> {
container.removeAllViews();
ColorFilterView view = new ColorFilterView(ctx);
BlurMaskFilter filter = new BlurMaskFilter(50, BlurMaskFilter.Blur.NORMAL);
view.setFilters(null, filter);
container.addView(view, new FrameLayout.LayoutParams(Views.MATCH_PARENT, Views.MATCH_PARENT));
dialog.close();
});
//EmbossMaskFilter实现浮雕效果
dialog.onClick(R.id.menu2, () -> {
container.removeAllViews();
ColorFilterView view = new ColorFilterView(ctx);
EmbossMaskFilter filter = new EmbossMaskFilter(new float[]{-10, -10, 50}, 0.2f, 50, 50);
view.setFilters(null, filter);
container.addView(view, new FrameLayout.LayoutParams(Views.MATCH_PARENT, Views.MATCH_PARENT));
dialog.close();
});
//ColorMatrixColorFilter实现增红效果
//红色通道色彩值增加50,其它通道色彩值不变
dialog.onClick(R.id.menu3, () -> {
container.removeAllViews();
ColorFilterView view = new ColorFilterView(ctx);
ColorMatrix matrix = new ColorMatrix(new float[]{
1, 0, 0, 0, 50,
0, 1, 0, 0, 0,
0, 0, 1, 0, 0,
0, 0, 0, 1, 0
});
ColorMatrixColorFilter filter = new ColorMatrixColorFilter(matrix);
view.setFilters(filter, null);
container.addView(view, new FrameLayout.LayoutParams(Views.MATCH_PARENT, Views.MATCH_PARENT));
dialog.close();
});
//ColorMatrixColorFilter实现色彩增强效果
//所有通道色彩值按比例增大
dialog.onClick(R.id.menu4, () -> {
container.removeAllViews();
ColorFilterView view = new ColorFilterView(ctx);
ColorMatrix matrix = new ColorMatrix(new float[]{
1.5F, 0, 0, 0, 0,
0, 1.5F, 0, 0, 0,
0, 0, 1.5F, 0, 0,
0, 0, 0, 1, 0
});
ColorMatrixColorFilter filter = new ColorMatrixColorFilter(matrix);
view.setFilters(filter, null);
container.addView(view, new FrameLayout.LayoutParams(Views.MATCH_PARENT, Views.MATCH_PARENT));
dialog.close();
});
//ColorMatrixColorFilter实现灰度效果
//RGB通道色彩值全部相等,图片就是灰色的
//对每个RGB通道色彩值,取一定比率累加,只要比率之和为1,得到的新色彩值,亮度是不变的
dialog.onClick(R.id.menu5, () -> {
container.removeAllViews();
ColorFilterView view = new ColorFilterView(ctx);
ColorMatrix matrix = new ColorMatrix(new float[]{
0.333F, 0.333F, 0.333F, 0, 0,
0.333F, 0.333F, 0.333F, 0, 0,
0.333F, 0.333F, 0.333F, 0, 0,
0, 0, 0, 1, 0
});
ColorMatrixColorFilter filter = new ColorMatrixColorFilter(matrix);
view.setFilters(filter, null);
container.addView(view, new FrameLayout.LayoutParams(Views.MATCH_PARENT, Views.MATCH_PARENT));
dialog.close();
});
//ColorMatrixColorFilter实现底片效果
//RGB通道色彩值全部取反
dialog.onClick(R.id.menu6, () -> {
container.removeAllViews();
ColorFilterView view = new ColorFilterView(ctx);
ColorMatrix matrix = new ColorMatrix(new float[]{
-1, 0, 0, 0, 255,
0, -1, 0, 0, 255,
0, 0, -1, 0, 255,
0, 0, 0, 1, 0
});
ColorMatrixColorFilter filter = new ColorMatrixColorFilter(matrix);
view.setFilters(filter, null);
container.addView(view, new FrameLayout.LayoutParams(Views.MATCH_PARENT, Views.MATCH_PARENT));
dialog.close();
});
//ColorMatrixColorFilter实现复古效果
//RGB通道色彩值全部取反
dialog.onClick(R.id.menu7, () -> {
container.removeAllViews();
ColorFilterView view = new ColorFilterView(ctx);
ColorMatrix matrix = new ColorMatrix(new float[]{
0.5F, 0.5F, 0.5F, 0, 0,
0.333F, 0.333F, 0.333F, 0, 0,
0.25F, 0.25F, 0.25F, 0, 0,
0, 0, 0, 1, 0
});
ColorMatrixColorFilter filter = new ColorMatrixColorFilter(matrix);
view.setFilters(filter, null);
container.addView(view, new FrameLayout.LayoutParams(Views.MATCH_PARENT, Views.MATCH_PARENT));
dialog.close();
});
}
}
源码下载
Canvas特效之Filter.zip