Android系统中封装了ColorMatrix类,就是颜色矩阵,通过这个类可以很方便的改变矩阵值来处理颜色效果。创建一个ColorMatrix和创建普通类是一样的。
ColorMatrix中改变色光属性的几个方法:
setRotate(axis, degrees):设置颜色的色调。
第一个参数:系统分别用了0,1,2代表Red,Green,Blue三种颜色的处理。
第二个参数:需要处理的值。
ColorMatrix hueMatrix = new ColorMatrix();
hueMatrix.setRotate(0, hue);
hueMatrix.setRotate(1, hue);
hueMatrix.setRotate(2, hue);
ColorMatrix saturationMatrix = new ColorMatrix();
saturationMatrix.setSaturation(saturation);
setScale(rScale, gScale, bScale, aScale):设置图像亮度,当三原色以相同比例混合时,就会显示出白色,当亮度为0时,图像就全黑了。
ColorMatrix lumMatrix = new ColorMatrix();
lumMatrix.setScale(lum, hue, saturation, 1);
ColorMatrix colorMatrix = new ColorMatrix();
colorMatrix.postConcat(hueMatrix);
colorMatrix.postConcat(saturationMatrix);
colorMatrix.postConcat(lumMatrix);
package com.example.androidcolormatrix;
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.Paint;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
public class SeekBarActivity extends Activity implements OnSeekBarChangeListener {
private ImageView imageView;
private Bitmap bitmap;
private SeekBar seekbarHue,seekbarSaturation,seekbarLum;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//初始化组件
imageView = (ImageView) findViewById(R.id.imageView);
seekbarHue = (SeekBar) findViewById(R.id.seekbarHue);
seekbarSaturation = (SeekBar) findViewById(R.id.seekbarSaturation);
seekbarLum = (SeekBar) findViewById(R.id.seekbarLum);
//给拖动条设置初值
seekbarHue.setProgress(50);
seekbarSaturation.setProgress(50);
seekbarLum.setProgress(50);
//给imageview添加位图
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.we);
imageView.setImageBitmap(bitmap);
//给拖动条添加监听
seekbarHue.setOnSeekBarChangeListener(this);
seekbarSaturation.setOnSeekBarChangeListener(this);
seekbarLum.setOnSeekBarChangeListener(this);
}
//设置ColorMatrix返回设置之后的位图
private Bitmap handleImage(Bitmap bm, float hue, float saturation, float lum){
Bitmap bmp = Bitmap.createBitmap(bm.getWidth(), bm.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bmp);
Paint paint = new Paint();
ColorMatrix hueMatrix = new ColorMatrix();
hueMatrix.setRotate(0, hue);
hueMatrix.setRotate(1, hue);
hueMatrix.setRotate(2, hue);
ColorMatrix saturationMatrix = new ColorMatrix();
saturationMatrix.setSaturation(saturation);
ColorMatrix lumMatrix = new ColorMatrix();
lumMatrix.setScale(lum, hue, saturation, 1);
ColorMatrix colorMatrix = new ColorMatrix();
colorMatrix.postConcat(hueMatrix);
colorMatrix.postConcat(saturationMatrix);
colorMatrix.postConcat(lumMatrix);
paint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
canvas.drawBitmap(bm, 0, 0, paint);
return bmp;
}
@Override
public void onProgressChanged(SeekBar bar, int progress, boolean fromUser){
float mHue = 0;
float mSaturation = 0;
float mLum = 0;
float MID_VALUE = 50;
switch (bar.getId()) {
case R.id.seekbarHue:
mHue = (progress - MID_VALUE) * 1.0F / MID_VALUE * 180;
break;
case R.id.seekbarSaturation:
mSaturation = progress * 1.0F / MID_VALUE;
break;
case R.id.seekbarLum:
mLum = progress * 1.0F / MID_VALUE;
break;
default:
break;
}
imageView.setImageBitmap(handleImage(bitmap, mHue, mSaturation, mLum));
}
@Override
public void onStartTrackingTouch(SeekBar arg0) {
// TODO Auto-generated method stub
}
@Override
public void onStopTrackingTouch(SeekBar arg0) {
// TODO Auto-generated method stub
}
}
效果图:
具体分析一下颜色矩阵:
mycolormatrix.xml:
package com.example.androidcolormatrix;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.GridLayout;
import android.widget.ImageView;
public class MyColorMatrixActivity extends Activity {
private ImageView imageView;
private GridLayout group;
private Bitmap bitmap;
private EditText[] edits = new EditText[20];
private float[] editstext = new float[20];
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mycolormatrix);
//初始化组件
imageView = (ImageView) findViewById(R.id.imageView);
group = (GridLayout) findViewById(R.id.group);
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.we);
imageView.setImageBitmap(bitmap);
group.post(new Runnable() {
public void run() {
addEdits();
fillEdits();
}
});
}
//生成并添加20个编辑框
private void addEdits(){
for (int i = 0; i < 20; i++) {
edits[i] = new EditText(MyColorMatrixActivity.this);
edits[i].setHeight(group.getHeight() / 4);
edits[i].setWidth(group.getWidth() / 5);
group.addView(edits[i]);
}
}
//为20个编辑框赋初值
private void fillEdits(){
for (int i = 0; i < 20; i++) {
if(i % 6 == 0){
edits[i].setText(String.valueOf(1));
}else{
edits[i].setText(String.valueOf(0));
}
}
}
public void onClickChange(View view){
getAndSetImageView();
}
public void onClickReseet(View view){
fillEdits();
getAndSetImageView();
}
private void getAndSetImageView(){
for (int i = 0; i < 20; i++) {
editstext[i] = Float.valueOf(edits[i].getText().toString());
}
Bitmap bmp = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888);
ColorMatrix colorMatrix = new ColorMatrix();
colorMatrix.set(editstext);
Canvas canvas = new Canvas(bmp);
Paint paint = new Paint();
paint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
canvas.drawBitmap(bitmap, 0, 0, paint);
imageView.setImageBitmap(bmp);
}
}
灰度效果:
0.33 , 0.59 , 0.11 , 0 , 0
0.33 , 0.59 , 0.11 , 0 , 0
0.33 , 0.59 , 0.11 , 0 , 0
0 , 0 , 0 , 1 , 0
图像反转:
-1 , 0 , 0 , 1 , 1
0 , -1 ,0 , 1 , 1
0 , 0 , -1 , 1 , 1
0 , 0 , 0 , 1 ,0
怀旧效果:
0.393 , 0.769 , 0.189 , 0 , 0
0.349 , 0.686 , 0.168 , 0 ,0
0.272 , 0.543 , 0.131 ,0 ,0
0 , 0 ,0 ,1 ,0
去色效果:
1.5 , 1.5 , 1.5 , 0 , -1
1.5 , 1.5 , 1.5 , 0 , -1
1.5 , 1.5 , 1.5 , 0 , -1
0 , 0 ,0 , 1 ,0
高饱和度:
1.438 , -0.122 , -0.016 , 0 , -0.03
-0.062, 1.378 , -0.016 , 0 , 0.05
-0.062, -0.122 ,1.438, 0 , -0.02
0 , 0 , 0 , 1 ,0
通过改变每个像素点的具体ARGB,可以更加精确地处理图像。
注意:传递进来的原始图片是不能修改的,一般根据原始图片生成一张新的图片来修改。
使用的方法;
bitmap.getPixels(pixels, offset, stride, x, y, width, height):
pixels:接收位图颜色值的数组
offset:写入到pixels[]中的第一个像素索引值
stride:pixels[]中的行间距
x:从位图中读取的第一个像素的x坐标
y:从位图中读取的第一个像素的y坐标
width:从每一行中读取的像素宽度
height:读取的行数
通常情况下使用:bitmap.getPixels(pixels, 0, bitmap.getWidth(), 0, 0, width, height);
bitmap.setPixels(pixels, 0, bitmap.getWidth(), 0, 0, width, height);
介绍几种常用的处理效果算法:
底片效果:r = 255 - r;
g = 255 - g;
b = 255 - b;
老照片效果:r = (int) (0.393*r+0.769*g+0.189*b);
浮雕效果:B.r = C.r - B.r + 127;
B.g = C.g - B.g + 127;
B.b = C.b - B.b + 127;
代码:
negative.xml:
package com.example.androidcolormatrix;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.os.Bundle;
import android.widget.ImageView;
public class NegativeActivity extends Activity {
private ImageView imageView;
private Bitmap bitmap;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.negative);
imageView = (ImageView) findViewById(R.id.imageView);
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.we);
imageView.setImageBitmap(handleImageNegative1(bitmap));
}
//底片效果
private Bitmap handleImageNegative(Bitmap bm){
int width = bm.getWidth();
int height = bm.getHeight();
int color;
int r,g,b,a;
Bitmap bmp = Bitmap.createBitmap(width, height, Config.ARGB_8888);
int[] oldPx = new int[width*height];
int[] newPx = new int[width*height];
bm.getPixels(oldPx, 0, width, 0, 0, width, height);
for(int i = 0; i 255){
r = 255;
}else if(r < 0){
r = 0;
}
if(g > 255){
g = 255;
}else if(g < 0){
g = 0;
}
if(b > 255){
b = 255;
}else if(b < 0){
b = 0;
}
newPx[i] = Color.argb(a, r, g, b);
}
bmp.setPixels(newPx, 0, width, 0, 0, width, height);
return bmp;
}
private Bitmap handleImageNegative1(Bitmap bm){
int width = bm.getWidth();
int height = bm.getHeight();
int color;
int r,g,b,a;
Bitmap bmp = Bitmap.createBitmap(width, height, Config.ARGB_8888);
int[] oldPx = new int[width*height];
int[] newPx = new int[width*height];
bm.getPixels(oldPx, 0, width, 0, 0, width, height);
for(int i = 1; i 255){
r = 255;
}else if(r < 0){
r = 0;
}
if(g > 255){
g = 255;
}else if(g < 0){
g = 0;
}
if(b > 255){
b = 255;
}else if(b < 0){
b = 0;
}
newPx[i] = Color.argb(a, r, g, b);
}
bmp.setPixels(newPx, 0, width, 0, 0, width, height);
return bmp;
}
//老照片效果
private Bitmap handleImageNegative2(Bitmap bm){
int width = bm.getWidth();
int height = bm.getHeight();
int color;
int r,g,b,a;
Bitmap bmp = Bitmap.createBitmap(width, height, Config.ARGB_8888);
int[] oldPx = new int[width*height];
int[] newPx = new int[width*height];
bm.getPixels(oldPx, 0, width, 0, 0, width, height);
for(int i = 0; i 255){
r = 255;
}else if(r < 0){
r = 0;
}
if(g > 255){
g = 255;
}else if(g < 0){
g = 0;
}
if(b > 255){
b = 255;
}else if(b < 0){
b = 0;
}
newPx[i] = Color.argb(a, r, g, b);
}
bmp.setPixels(newPx, 0, width, 0, 0, width, height);
return bmp;
}
}
源码下载:http://download.csdn.net/detail/fancheng614/9921341