Android--ColorMatrix改变图片颜色

时间:2023-03-09 18:55:47
Android--ColorMatrix改变图片颜色

前言

  本篇博客讲解如何通过改变图片像素点RGB的值的方式,在Android中改变图片的颜色。在最后将以一个简单的Demo来作为演示。

  本篇博客的主要内容:

  1. ColorMatrix
  2. 使用ColorMatrix改变图片颜色的步骤
  3. 改变图片RGBA值的Demo

ColorMatrix

  在Android中,图片是以一个个RGBA的像素点的形式加载到内存中的,所以如果需要改变图片的颜色,就需要针对这一个个像素点的RGBA的值进行修改,其实主要是RGB,A是透明度。在Android下,修改图片RGBA的值需要ColorMatrix类的支持,它定义了一个5*4的float[]类型的矩阵,矩阵中每一行表示RGBA中的一个参数。

  一般常用指定ColorMatrix的RGBA值的方式有两种:

  • 通过构造函数ColorMatrix(float[] src)直接得到i一个ColorMatrix对象,其中src参数为5*4的float[]类型的矩阵。
  • 通过构造函数ColorMatrix()得到ColorMatrix对象,再通过set(float[] src)指定一个5*4的float[]类型的矩阵。

  下面是定义了一个不修改的原图的RGBA的ColorMatrix。

         ColorMatrix colorMatrix = new ColorMatrix();
colorMatrix.set(new float[] {
1, 0, 0, 0, 0,
0, 1, 0, 0, 0,
0, 0, 1,0, 0,
0, 0, 0, 1, 0
});

  可以看到,代码中,第三行定义的是R,第四行定义的是G,第五行定义的是B,第六行定义的是A。在定义的时候,需要注意数组的顺序必须正确。

  这个矩阵定义的是一连串float数组,其中不同的位置代表了不同的RGBA值,它的范围在0.0f~2.0f之间,1为保持原图的RGBA值。

使用ColorMatrix改变图片颜色的步骤

  上面介绍了ColorMatrix设置图片的颜色,但是仅仅使用它还无法完成图片颜色的修改,需要配合Canvas和Paint使用,具体步骤如下:

  1. 通过Bitmap.createBitmap()方法获得一个空白的Bitmap对象。
  2. 定义Paint独享,通过Paint.setColorFilter(ColorFilter)方法设置Paint的RGBA值。
  3. 使用Canvas.drawBitmap()方法把原图使用定义的Paint画到空白的Bitmap对象上即可获得改变RGBA值后的图像。

  需要说明一下的是Paint.setColorFilter()方法传递的是一个ColorFilter对象,可以使用它的子类ColorMatrixColorFilter包装我们定义好的ColorMatrix。

改变图片RGBA值的Demo

  上面已经简单讲解了如何使用ColorMatrix定义一个RGBA值的矩阵,然后介绍了使用ColorMatrix的步骤,下面通过一个简单的Demo来演示如何使用它。在Demo中定义了四个SeekBar,分别代表RGBA,拖动其中的某个SeekBar,改变位图原本的颜色。注释都比较全,这里就不再赘述了。

  布局代码:

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" > <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="R" /> <SeekBar
android:id="@+id/sb_red"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="255"
android:progress="128" /> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="G" /> <SeekBar
android:id="@+id/sb_green"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="255"
android:progress="128" /> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="B" /> <SeekBar
android:id="@+id/sb_blue"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="255"
android:progress="128" /> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="A" /> <SeekBar
android:id="@+id/sb_alpha"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="255"
android:progress="128" /> <ImageView
android:id="@+id/iv_show"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/painter" /> </LinearLayout>

  实现代码:

 package cn.bgxt.colormatrixdemo;

 import android.os.Bundle;
import android.util.Log;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Matrix;
import android.graphics.Paint; public class MainActivity extends Activity {
private SeekBar sb_red, sb_green, sb_blue,sb_alpha;
private ImageView iv_show;
private Bitmap afterBitmap;
private Paint paint;
private Canvas canvas;
private Bitmap baseBitmap; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); iv_show = (ImageView) findViewById(R.id.iv_show);
sb_red = (SeekBar) findViewById(R.id.sb_red);
sb_green = (SeekBar) findViewById(R.id.sb_green);
sb_blue = (SeekBar) findViewById(R.id.sb_blue);
sb_alpha = (SeekBar) findViewById(R.id.sb_alpha); sb_red.setOnSeekBarChangeListener(seekBarChange);
sb_green.setOnSeekBarChangeListener(seekBarChange);
sb_blue.setOnSeekBarChangeListener(seekBarChange);
sb_alpha.setOnSeekBarChangeListener(seekBarChange); // 从资源文件中获取图片
baseBitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.painter);
// 获取一个与baseBitmap大小一致的可编辑的空图片
afterBitmap = Bitmap.createBitmap(baseBitmap.getWidth(),
baseBitmap.getHeight(), baseBitmap.getConfig());
canvas = new Canvas(afterBitmap);
paint = new Paint();
} private SeekBar.OnSeekBarChangeListener seekBarChange = new OnSeekBarChangeListener() { @Override
public void onStopTrackingTouch(SeekBar seekBar) {
// 获取每个SeekBar当前的值
float progressR = sb_red.getProgress()/128f;
float progressG = sb_green.getProgress()/128f;
float progressB = sb_blue.getProgress()/128f;
float progressA=sb_alpha.getProgress()/128f;
Log.i("main", "R:G:B="+progressR+":"+progressG+":"+progressB);
// 根据SeekBar定义RGBA的矩阵
float[] src = new float[]{
progressR, 0, 0, 0, 0,
0, progressG, 0, 0, 0,
0, 0, progressB, 0, 0,
0, 0, 0, progressA, 0};
// 定义ColorMatrix,并指定RGBA矩阵
ColorMatrix colorMatrix = new ColorMatrix();
colorMatrix.set(src);
// 设置Paint的颜色
paint.setColorFilter(new ColorMatrixColorFilter(src));
// 通过指定了RGBA矩阵的Paint把原图画到空白图片上
canvas.drawBitmap(baseBitmap, new Matrix(), paint);
iv_show.setImageBitmap(afterBitmap);
} @Override
public void onStartTrackingTouch(SeekBar seekBar) {
} @Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
}
};
}

  效果展示:
Android--ColorMatrix改变图片颜色Android--ColorMatrix改变图片颜色

  源码下载

Android--ColorMatrix改变图片颜色