Android ColorMatrixColorFilter

Android ( ColorMatrixColorFilter ) 颜色矩阵颜色滤镜通过一个 4x 5 的颜色矩阵来变换颜色,可以修改像素的饱和度,将 YUV 转换成 RGB 等

相关知识

RGB

RGB 就是红绿蓝,光的三基色

Red 红

Green 绿

Blue 蓝

RGBA 模型

RGBA 就是 RGB + Alpha (透明度)

色调/色相

三原色指色彩中不能再分解的三种基本颜色,通常说的三原色,即品红、黄、青 (是青不是蓝,蓝是品红和青混合的颜色)

三原色可以混合出所有的颜色,同时相加为黑色,黑白灰属于无色系

三原色是物体传递的颜色

饱和度

颜色的纯度,从 0(灰) 到 100%(饱和) 来进行描述

亮度/明度

颜色的相对明暗程度

ColorMatrix

颜色矩阵( 4x5 ),我们可以修改矩阵中的值,来实现黑白照,泛黄老照片,高对比度等效果

手撕颜色矩阵解释图如下

拿颜色矩阵的每一行来 * 颜色矩阵分量的每一列

很典型的一个例子,处理前后的结果比较,我们还可以让 某个颜色值 * 一个常数 ,比如让第三行(蓝)乘以 2,效果就变成泛蓝色了

验证 ColorMatrix 所起的作用

一个 ImageView,4x5 个 EditText,一个重置按钮和一个生成按钮,

依次是原图,泛黄,泛绿,泛红,高对比度,色相变换,以及黄色复古

  1. 创建一个 空的 Android 项目 cn.twle.android.ColorMatrix

  2. 下载 /static/i/mychild.png 并放到 res/drawable 目录

  3. 修改布局文件 activity_main.xml

    <?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:orientation="vertical"
        android:padding="5dp">
    
        <ImageView
            android:id="@+id/img_show"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="2" />
    
        <GridLayout
            android:id="@+id/gp_matrix"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="3"
            android:columnCount="5"
            android:rowCount="4"></GridLayout>
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <Button
                android:id="@+id/btn_reset"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="重置" />
            <Button
                android:id="@+id/btn_Change"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="变换" />
        </LinearLayout>
    </LinearLayout>
    
  4. 修改 MainActivity.java

    package cn.twle.android.colormatrix;
    
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.Canvas;
    import android.graphics.ColorMatrixColorFilter;
    import android.graphics.Paint;
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.view.View;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.GridLayout;
    import android.widget.ImageView;
    
    public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    
        private ImageView img_show;
        private GridLayout gp_matrix;
        private Button btn_reset;
        private Button btn_Change;
        private Bitmap mBitmap;
        private int mEtWidth, mEtHeight;
        private EditText[] mEts = new EditText[20];
        private float[] mColorMatrix = new float[20];
        private Context mContext;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            mContext = MainActivity.this;
            bindViews();
    
            gp_matrix.post(new Runnable() {
                @Override
                public void run() {
                    mEtWidth = gp_matrix.getWidth() / 5;
                    mEtHeight = gp_matrix.getHeight() / 4;
                    //添加5 * 4EditText
                    for (int i = 0; i < 20; i++) {
                        EditText editText = new EditText(mContext);
                        mEts[i] = editText;
                        gp_matrix.addView(editText, mEtWidth, mEtHeight);
                    }
                    initMatrix();
                }
            });
        }
    
        private void bindViews() {
            img_show = (ImageView) findViewById(R.id.img_show);
            gp_matrix = (GridLayout) findViewById(R.id.gp_matrix);
            btn_reset = (Button) findViewById(R.id.btn_reset);
            btn_Change = (Button) findViewById(R.id.btn_Change);
    
            mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.mychild);
            img_show.setImageBitmap(mBitmap);
    
            btn_reset.setOnClickListener(this);
            btn_Change.setOnClickListener(this);
        }
    
        //定义一个初始化颜色矩阵的方法
        private void initMatrix() {
            for (int i = 0; i < 20; i++) {
                if (i % 6 == 0) {
                    mEts[i].setText(String.valueOf(1));
                } else {
                    mEts[i].setText(String.valueOf(0));
                }
            }
        }
    
        //定义一个获取矩阵值得方法
        private void getMatrix() {
            for (int i = 0; i < 20; i++) {
                mColorMatrix[i] = Float.valueOf(mEts[i].getText().toString());
            }
        }
    
        //根据颜色矩阵的值来处理图片
        private void setImageMatrix() {
            Bitmap bmp = Bitmap.createBitmap(mBitmap.getWidth(), mBitmap.getHeight(),
                    Bitmap.Config.ARGB_8888);
            android.graphics.ColorMatrix colorMatrix = new android.graphics.ColorMatrix();
            colorMatrix.set(mColorMatrix);
    
            Canvas canvas = new Canvas(bmp);
            Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
            paint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
            canvas.drawBitmap(mBitmap, 0, 0, paint);
            img_show.setImageBitmap(bmp);
        }
    
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.btn_Change:
                    getMatrix();
                    setImageMatrix();
                    break;
                case R.id.btn_reset:
                    initMatrix();
                    getMatrix();
                    setImageMatrix();
                    break;
            }
        }
    }
    

post() 方法是为了保证 GridLayout 加载完毕后才去获取长宽,不然在获取 GridLayout 长 宽的时候可是获取不到值的

参考文档

  1. 颜色矩阵颜色过滤器 ColorMatrixColorFilter

Android 基础教程

关于   |   FAQ   |   我们的愿景   |   广告投放   |  博客

  简单教程,简单编程 - IT 入门首选站

Copyright © 2013-2022 简单教程 twle.cn All Rights Reserved.