承香墨影
Android--ColorMatrix改變圖片顏色
前言
本篇博客講解如何通過改變圖片像素點RGB的值的方式,在Android中改變圖片的顏色。在最後將以一個簡單的Demo來作為演示。
本篇博客的主要內容:
ColorMatrix
使用ColorMatrix改變圖片顏色的步驟
改變圖片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。
1 ColorMatrix colorMatrix = new ColorMatrix();
2 colorMatrix.set(new float[] {
3 1, 0, 0, 0, 0,
4 0, 1, 0, 0, 0,
5 0, 0, 1,0, 0,
6 0, 0, 0, 1, 0
7 });
可以看到,代碼中,第三行定義的是R,第四行定義的是G,第五行定義的是B,第六行定義的是A。在定義的時候,需要注意數組的順序必須正確。
這個矩陣定義的是一連串float數組,其中不同的位置代表了不同的RGBA值,它的范圍在0.0f~2.0f之間,1為保持原圖的RGBA值。
使用ColorMatrix改變圖片顏色的步驟
上面介紹了ColorMatrix設置圖片的顏色,但是僅僅使用它還無法完成圖片顏色的修改,需要配合Canvas和Paint使用,具體步驟如下:
通過Bitmap.createBitmap()方法獲得一個空白的Bitmap對象。
定義Paint獨享,通過Paint.setColorFilter(ColorFilter)方法設置Paint的RGBA值。
使用Canvas.drawBitmap()方法把原圖使用定義的Paint畫到空白的Bitmap對象上即可獲得改變RGBA值後的圖像。
需要說明一下的是Paint.setColorFilter()方法傳遞的是一個ColorFilter對象,可以使用它的子類ColorMatrixColorFilter包裝我們定義好的ColorMatrix。
改變圖片RGBA值的Demo
上面已經簡單講解了如何使用ColorMatrix定義一個RGBA值的矩陣,然後介紹了使用ColorMatrix的步驟,下面通過一個簡單的Demo來演示如何使用它。在Demo中定義了四個SeekBar,分別代表RGBA,拖動其中的某個SeekBar,改變位圖原本的顏色。注釋都比較全,這裡就不再贅述了。
布局代碼:
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
2 xmlns:tools="http://schemas.android.com/tools"
3 android:layout_width="match_parent"
4 android:layout_height="match_parent"
5 android:orientation="vertical"
6 android:paddingBottom="@dimen/activity_vertical_margin"
7 android:paddingLeft="@dimen/activity_horizontal_margin"
8 android:paddingRight="@dimen/activity_horizontal_margin"
9 android:paddingTop="@dimen/activity_vertical_margin"
10 tools:context=".MainActivity" >
11
12 <TextView
13 android:layout_width="wrap_content"
14 android:layout_height="wrap_content"
15 android:text="R" />
16
17 <SeekBar
18 android:id="@+id/sb_red"
19 android:layout_width="match_parent"
20 android:layout_height="wrap_content"
21 android:max="255"
22 android:progress="128" />
23
24 <TextView
25 android:layout_width="wrap_content"
26 android:layout_height="wrap_content"
27 android:text="G" />
28
29 <SeekBar
30 android:id="@+id/sb_green"
31 android:layout_width="match_parent"
32 android:layout_height="wrap_content"
33 android:max="255"
34 android:progress="128" />
35
36 <TextView
37 android:layout_width="wrap_content"
38 android:layout_height="wrap_content"
39 android:text="B" />
40
41 <SeekBar
42 android:id="@+id/sb_blue"
43 android:layout_width="match_parent"
44 android:layout_height="wrap_content"
45 android:max="255"
46 android:progress="128" />
47
48 <TextView
49 android:layout_width="wrap_content"
50 android:layout_height="wrap_content"
51 android:text="A" />
52
53 <SeekBar
54 android:id="@+id/sb_alpha"
55 android:layout_width="match_parent"
56 android:layout_height="wrap_content"
57 android:max="255"
58 android:progress="128" />
59
60 <ImageView
61 android:id="@+id/iv_show"
62 android:layout_width="wrap_content"
63 android:layout_height="wrap_content"
64 android:src="@drawable/painter" />
65
66 </LinearLayout>
實現代碼:
1 package cn.bgxt.colormatrixdemo;
2
3 import android.os.Bundle;
4 import android.util.Log;
5 import android.widget.ImageView;
6 import android.widget.SeekBar;
7 import android.widget.SeekBar.OnSeekBarChangeListener;
8 import android.app.Activity;
9 import android.graphics.Bitmap;
10 import android.graphics.BitmapFactory;
11 import android.graphics.Canvas;
12 import android.graphics.ColorMatrix;
13 import android.graphics.ColorMatrixColorFilter;
14 import android.graphics.Matrix;
15 import android.graphics.Paint;
16
17 public class MainActivity extends Activity {
18 private SeekBar sb_red, sb_green, sb_blue,sb_alpha;
19 private ImageView iv_show;
20 private Bitmap afterBitmap;
21 private Paint paint;
22 private Canvas canvas;
23 private Bitmap baseBitmap;
24
25 @Override
26 protected void onCreate(Bundle savedInstanceState) {
27 super.onCreate(savedInstanceState);
28 setContentView(R.layout.activity_main);
29
30 iv_show = (ImageView) findViewById(R.id.iv_show);
31 sb_red = (SeekBar) findViewById(R.id.sb_red);
32 sb_green = (SeekBar) findViewById(R.id.sb_green);
33 sb_blue = (SeekBar) findViewById(R.id.sb_blue);
34 sb_alpha = (SeekBar) findViewById(R.id.sb_alpha);
35
36 sb_red.setOnSeekBarChangeListener(seekBarChange);
37 sb_green.setOnSeekBarChangeListener(seekBarChange);
38 sb_blue.setOnSeekBarChangeListener(seekBarChange);
39 sb_alpha.setOnSeekBarChangeListener(seekBarChange);
40
41 // 從資源文件中獲取圖片
42 baseBitmap = BitmapFactory.decodeResource(getResources(),
43 R.drawable.painter);
44 // 獲取一個與baseBitmap大小一致的可編輯的空圖片
45 afterBitmap = Bitmap.createBitmap(baseBitmap.getWidth(),
46 baseBitmap.getHeight(), baseBitmap.getConfig());
47 canvas = new Canvas(afterBitmap);
48 paint = new Paint();
49 }
50
51 private SeekBar.OnSeekBarChangeListener seekBarChange = new OnSeekBarChangeListener() {
52
53 @Override
54 public void onStopTrackingTouch(SeekBar seekBar) {
55 // 獲取每個SeekBar當前的值
56 float progressR = sb_red.getProgress()/128f;
57 float progressG = sb_green.getProgress()/128f;
58 float progressB = sb_blue.getProgress()/128f;
59 float progressA=sb_alpha.getProgress()/128f;
60 Log.i("main", "R:G:B="+progressR+":"+progressG+":"+progressB);
61 // 根據SeekBar定義RGBA的矩陣
62 float[] src = new float[]{
63 progressR, 0, 0, 0, 0,
64 0, progressG, 0, 0, 0,
65 0, 0, progressB, 0, 0,
66 0, 0, 0, progressA, 0};
67 // 定義ColorMatrix,並指定RGBA矩陣
68 ColorMatrix colorMatrix = new ColorMatrix();
69 colorMatrix.set(src);
70 // 設置Paint的顏色
71 paint.setColorFilter(new ColorMatrixColorFilter(src));
72 // 通過指定了RGBA矩陣的Paint把原圖畫到空白圖片上
73 canvas.drawBitmap(baseBitmap, new Matrix(), paint);
74 iv_show.setImageBitmap(afterBitmap);
75 }
76
77 @Override
78 public void onStartTrackingTouch(SeekBar seekBar) {
79 }
80
81 @Override
82 public void onProgressChanged(SeekBar seekBar, int progress,
83 boolean fromUser) {
84 }
85 };
86 }
效果展示: