Android:滤镜效果ColorMatrix用法一

Android:滤镜效果ColorMatrix用法一_第1张图片
点击这里看视频演示效果

简单说说

我们的实现的效果是类似photoshop,调节RGB三通道的比重、透明度、色彩饱和度

先回答这个问题,把大象放冰箱需要几步?

  1. 打开冰箱门
  2. 把大象放进去
  3. 关上冰箱门

给定一个bitmap,调节RGB三通道的比重、透明度、色彩饱和度需要几步?

  1. 构建画布

    注意:先复制一张跟原图一模一样的bitmap,不能在原图上做修改

  2. 构建画笔

    注意:构建一个画笔,然后给画笔设置setColorFilter,这里需要传入ColorMatrix(关键就是这个ColorMatrix)

    切记,不能使用colorMatrix.setRotate()连续设置各个通道的色调,这样的话,会让最后一个覆盖前面的效果,而是要通过postConcat混合多个ColorMatrix

  3. 用构建好的画笔,在构建好的画布上画这个bitmap

直接上工具类

代码注释写的很清楚了

package performance.brilliant.com.brilliantperformance.view;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;

/**
 * 描述当前版本功能
 *
 * @Project: BrilliantPerformance
 * @author: cjx
 * @date: 2019-07-18 21:55  星期四
 */
public class ImageHelper {
    /**
     * @param srcBitmap  要改变的原图,注意不要在这个原图上做修改,要复制一张图出来做修改
     * @param hueR       红色调    越大,红色越浓重
     * @param hueG       绿色调    越大,绿色越浓重
     * @param hueB       蓝色调    越大,蓝色越浓重
     * @param saturation 饱和度    颜色丰富程度:0表示黑白效果;越大,颜色越艳丽
     * @param lumR       红亮度     明暗程度:0表示红色亮度为黑,越大越白
     * @param lumG       绿亮度     明暗程度:0表示绿色亮度为黑,越大越白
     * @param lumB       蓝亮度     明暗程度:0表示蓝色亮度为黑,越大越白
     * @param lumA       透明度亮度  明暗程度:0表示透明度为黑,越大越白
     * @return  变换后的bitmap     https://www.jianshu.com/p/9a44d04f39fc
     */

    public static Bitmap handlerImageEffect(Bitmap srcBitmap,
                                            float hueR, float hueG, float hueB,
                                            float saturation,
                                            float lumR, float lumG, float lumB, float lumA) {

        // ****************************    一、构建画布,新的bitmap画布   ****************************

        // 先复制一张跟原图一模一样的bitmap,不能在原图上做修改
        Bitmap newBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), Bitmap.Config.ARGB_8888);
        // 注意这里是new了一个新的Canvas,把newBitmap与他绑定在一起
        Canvas canvas = new Canvas(newBitmap);


        // ****************************    二、构建画笔,画笔要设置ColorMatrixColorFilter  ****************************

        // ColorMatrixColorFilter需要一个ColorMatrix参数
        // ColorMatrix可以通过postConcat把各种ColorMatrix进行混合
        // ColorMatrix的api支持设置 色调、饱和度、亮度(其实本质上是对4*5颜色矩阵的封装)


        // ★★★★★切记,不能使用setRotate连续设置各个通道的色调(如下段注释掉的代码),这样的话,会让最后一个覆盖前面的效果

        //        mHueMatrix.setRotate(0, mHueValue);
        //        mHueMatrix.setRotate(1, mHueValue);
        //        mHueMatrix.setRotate(2, mHueValue);

        // ★★★★★★应该按照下面的代码为 设置三个不同的hueMatrix,最后通过postConcat混合效果


        //色调 RGB每个颜色通道的值,越大,颜色越浓重
        ColorMatrix hueRedMatrix = new ColorMatrix();
        hueRedMatrix.setRotate(0, hueR);// axis=0:RED color

        ColorMatrix hueGreenMatrix = new ColorMatrix();
        hueGreenMatrix.setRotate(1, hueG);// axis=1:GREEN color

        ColorMatrix hueBlueMatrix = new ColorMatrix();
        hueBlueMatrix.setRotate(2, hueB);// axis=2:BLUE color


        //饱和度 颜色丰富程度:0表示黑白效果
        ColorMatrix saturationMatrix = new ColorMatrix();
        saturationMatrix.setSaturation(saturation);

        //亮度  明暗程度:0表示一片漆黑
        ColorMatrix lumMatrix = new ColorMatrix();
        lumMatrix.setScale(lumR, lumG, lumB, lumA);

        // 把所有的Matrix混合起来,构建一个ColorMatrix
        ColorMatrix imageMatrix = new ColorMatrix();

        imageMatrix.postConcat(hueRedMatrix);
        imageMatrix.postConcat(hueGreenMatrix);
        imageMatrix.postConcat(hueBlueMatrix);

        imageMatrix.postConcat(saturationMatrix);
        imageMatrix.postConcat(lumMatrix);


        //构建一支画笔
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        // 给画笔设置这个ColorMatrix
        paint.setColorFilter(new ColorMatrixColorFilter(imageMatrix));

        // ****************************    三、开始作画了, ****************************
        // 使用上面混合了ColorMatrix那只笔,
        // 在与newBitmap关联的的canvas上作画
        // 画什么,画的是原图srcBitmap
        canvas.drawBitmap(srcBitmap, 0, 0, paint);

        // 返回newBitmap
        return newBitmap;
    }


}

使用

package performance.brilliant.com.brilliantperformance;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.widget.ImageView;
import android.widget.SeekBar;

import performance.brilliant.com.brilliantperformance.view.ImageHelper;

public class LinearGradientActivity extends AppCompatActivity implements SeekBar.OnSeekBarChangeListener {

    private ImageView mImageView;
    private SeekBar bar_hueR;
    private SeekBar bar_hueG;
    private SeekBar bar_hueB;

    private SeekBar bar_saturation;

    private SeekBar bar_lumR;
    private SeekBar bar_lumG;
    private SeekBar bar_lumB;
    private SeekBar bar_lumA;
    private Bitmap mSrc;
    private Bitmap mBitmap;


    private Handler mHandler = new Handler();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_linear_gradient);

        initView();
        setListener();

        mSrc = BitmapFactory.decodeResource(getResources(), R.drawable.img_hudie);
    }

    private void setListener() {

        bar_hueR.setOnSeekBarChangeListener(this);
        bar_hueG.setOnSeekBarChangeListener(this);
        bar_hueB.setOnSeekBarChangeListener(this);

        bar_saturation.setOnSeekBarChangeListener(this);

        bar_lumR.setOnSeekBarChangeListener(this);
        bar_lumG.setOnSeekBarChangeListener(this);
        bar_lumB.setOnSeekBarChangeListener(this);
        bar_lumA.setOnSeekBarChangeListener(this);
    }

    private void initView() {
        mImageView = findViewById(R.id.ivc);

        bar_hueR = findViewById(R.id.bar_hueR);
        bar_hueG = findViewById(R.id.bar_hueG);
        bar_hueB = findViewById(R.id.bar_hueB);

        bar_saturation = findViewById(R.id.bar_saturation);


        bar_lumR = findViewById(R.id.bar_lumR);
        bar_lumG = findViewById(R.id.bar_lumG);
        bar_lumB = findViewById(R.id.bar_lumB);
        bar_lumA = findViewById(R.id.bar_lumA);
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                changeColor();
            }
        },300);

    }

    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        changeColor();
    }

    private void changeColor() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                mBitmap = ImageHelper.handlerImageEffect
                        (mSrc, bar_hueR.getProgress(),
                                bar_hueG.getProgress(),
                                bar_hueB.getProgress(),
                                bar_saturation.getProgress(),
                                bar_lumR.getProgress()*1.0f/100,
                                bar_lumG.getProgress()*1.0f/100,
                                bar_lumB.getProgress()*1.0f/100,
                                bar_lumA.getProgress()*1.0f/100);

                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        mImageView.setImageBitmap(mBitmap);
                    }
                });


            }
        }).start();
    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {

    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {

    }
}

你可能感兴趣的:(知识点)