App黑白化实现扩展,一键护眼模式,给App,学android的入门基础知识

if (window == null) {
return;
}
View view = window.getDecorView();
Paint paint = new Paint();
ColorMatrix cm = new ColorMatrix();
// 关键起作用的代码,Saturation,翻译成中文就是饱和度的意思。
// 官方文档说明:A value of 0 maps the color to gray-scale. 1 is identity.
// 原来如此,666
cm.setSaturation(0f);
paint.setColorFilter(new ColorMatrixC

《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》

【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 完整内容开源分享

olorFilter(cm));
view.setLayerType(View.LAYER_TYPE_HARDWARE, paint);

没了解过的可以看这两篇复习下:

App 黑白化实现探索,有一行代码实现的方案吗?

App 黑白化实现探索2, 发现了一种更方便的方案,我被锤了!

App黑白化实现扩展,一键护眼模式,给App,学android的入门基础知识_第1张图片

App黑白化实现扩展,一键护眼模式,给App,学android的入门基础知识_第2张图片

2拆招

我们的操作对象是 ColorMatrix,它具体是个什么东东官方文档最清楚了,把文档请出来:

4x5 matrix for transforming the color and alpha components of a Bitmap. The matrix can be passed as single array, and is treated as follows:
[ a, b, c, d, e,
f, g, h, i, j,
k, l, m, n, o,
p, q, r, s, t ]
When applied to a color [R, G, B, A], the resulting color is computed as:
R’ = aR + bG + cB + dA + e;
G’ = fR + gG + hB + iA + j;
B’ = kR + lG + mB + nA + o;
A’ = pR + qG + rB + sA + t;

「人」如其名,它是个 4x5 的矩阵,通过矩阵乘法和加法实现了颜色的转换,没看明白?这样能明白了吧:

App黑白化实现扩展,一键护眼模式,给App,学android的入门基础知识_第3张图片

那设置饱和度是如何影响颜色的呢?来看看 ColorMatrix.setSaturation 的具体实现

/**

  • Create a new colormatrix initialized to identity (as if reset() had
  • been called).
    /
    public ColorMatrix() {
    reset();
    }
    // 原始矩阵长这样
    /
    *
  • Set this colormatrix to identity:
  • [ 1 0 0 0 0 - red vector
  • 0 1 0 0 0 - green vector
  • 0 0 1 0 0 - blue vector
  • 0 0 0 1 0 ] - alpha vector
    */
    public void reset() {
    final float[] a = mArray;

for (int i = 19; i > 0; --i) {
a[i] = 0;
}
a[0] = a[6] = a[12] = a[18] = 1;
}
/**

  • Set the matrix to affect the saturation of colors.
  • @param sat A value of 0 maps the color to gray-scale. 1 is identity.
    */
    public void setSaturation(float sat) {
    reset();
    float[] m = mArray;
    final float invSat = 1 - sat;
    final float R = 0.213f * invSat;
    final float G = 0.715f * invSat;
    final float B = 0.072f * invSat;
    m[0] = R + sat; m[1] = G; m[2] = B;
    m[5] = R; m[6] = G + sat; m[7] = B;
    m[10] = R; m[11] = G; m[12] = B + sat;
    }

当我们设置饱和度sat为0时,上面矩阵里的a, f, k都变成了0.213f,b, g, l都变成了0.715f,c, h, m都变成了0.072f,代入计算公式发现R, G, B取值变成一样了,这不就变成黑白色了吗!

3亮招

通过前面的分析已经了清楚设置饱和度最终是通过修改矩阵来实现黑白色效果的,那我们直接修改矩阵呢?**比如护眼模式,不就是去蓝光吗!**上代码:

Window window = activity.getWindow();
if (window == null) {
return;
}
View view = window.getDecorView();
Paint paint = new Paint();
// 我们把蓝色减弱为原来的0.7
ColorMatrix cm = new ColorMatrix(new float[]{
1, 0, 0, 0, 0,
0, 1, 0, 0, 0,
0, 0, 0.7f, 0, 0,
0, 0, 0, 1, 0
});
paint.setColorFilter(new ColorMatrixColorFilter(cm));
view.setLayerType(View.LAYER_TYPE_HARDWARE, paint);

App黑白化实现扩展,一键护眼模式,给App,学android的入门基础知识_第4张图片

哟,真是神奇。

4连招

如果前面的分析你都看懂了,你可能意识到这个ColorMatrix玩法还有很多,比如夜间模式,可能就是反色+降低亮度,反色代码如下:

Window window = activity.getWindow();
if (window == null) {
return;
}
View view = window.getDecorView();
view.addOnLayoutChangeListener(this);
if (view instanceof ViewGroup) {
takeOffColor((ViewGroup) view);
}
Paint paint = new Paint();
ColorMatrix cm = new ColorMatrix(new float[]{
-1, 0, 0, 0, 255,
0, -1, 0, 0, 255,
0, 0, -1, 0, 255,
0, 0, 0, 1, 0
});
paint.setColorFilter(new ColorMatrixColorFilter(cm));
view.setLayerType(View.LAYER_TYPE_HARDWARE, paint);

App黑白化实现扩展,一键护眼模式,给App,学android的入门基础知识_第5张图片

**但是有一个很明显的问题,因为我们是对Activity的DecorView做了颜色转换,ImageView是它的Child,所以图片也被反色了,在购物的场景下我想买黄色的衣服,结果收到货确实蓝色的,闹呢?那我们能不能单独给ImageView设置一个反向的矩阵让图片恢复原来的颜色呢?**直接上逆矩阵:

// 遍历查找ImageView,对其设置逆矩阵
int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
能不能单独给ImageView设置一个反向的矩阵让图片恢复原来的颜色呢?**直接上逆矩阵:

// 遍历查找ImageView,对其设置逆矩阵
int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {

你可能感兴趣的:(程序员,面试,移动开发,android)