对图像进行颜色方面的处理,通过使用颜色矩阵(ColorMatrix)来实现。从而可以达到很多特效如黑白老照片、泛黄旧照片等等。
1.颜色矩阵(ColorMatrix)
这里有详细的介绍:http://developer.android.com/reference/android/graphics/ColorMatrix.html
不过是英文的,在这里我就先导读一下。
一张位图可以转换为一个5*4的矩阵,涉及到颜色和透明度。如图1所示。在Android中,颜色矩阵M是以一维数组m=[a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t]的方式进行存储的。
图1
在一张图片中,图像的RGBA(红色、绿色、蓝色、透明度)值决定了该图片所呈现出来的颜色效果。
而图像的RGBA值则存储在一个5*1的颜色分量矩阵C中,由颜色分量矩阵C可以控制图像的颜色效果。颜色分量矩阵C如图2所示。
图2
要想改变一张图片的颜色效果,只需要改变图像的颜色分量矩阵即可。通过颜色矩阵可以很方便的修改图像的颜色分量矩阵。假设修改后的图像颜色分量矩阵为C1,则有如图3所示的颜色分量矩阵计算公式。
图3
由此可见,通过颜色矩阵修改了原图像的RGBA值,从而达到了改变图片颜色效果的目的。并且,通过如图3所示的运算可知,颜色矩阵M的第一行参数abcde决定了图像的红色成分,第二行参数fghij决定了图像的绿色成分,第三行参数klmno决定了图像的蓝色成分,第四行参数pqrst决定了图像的透明度,第五列参数ejot是颜色的偏移量。
通常,改变颜色分量时可以通过修改第5列的颜色偏移量来实现,如图4所示的颜色矩阵M1,通过计算后可以得知该颜色矩阵的作用是使图像的红色分量和绿色分量均增加100,这样的效果就是图片泛黄(因为红色与绿色混合后得到黄色)。
图4
除此之外,也可以通过直接对颜色值乘以某一系数而达到改变颜色分量的目的。如图5所示的颜色矩阵M2,将绿色分量放大了2倍,这样的效果就是图片泛绿色。
图5
实例:
步骤一:我们首先自定义一个view,用来显示我们处理的图片。
ColorView.java
package com.mycolor;
import android.content.Context;
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.util.AttributeSet;
import android.widget.ImageView;
public class ColorView extends ImageView {
private Paint myPaint = null;
private Bitmap bitmap = null;
private ColorMatrix myColorMatrix = null;
private float[] colorArray = {1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0};
public ColorView(Context context, AttributeSet attrs)
{
super(context, attrs);
bitmap = BitmapFactory.decodeResource(context.getResources(),R.drawable.a2);
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//新建画笔对象
myPaint = new Paint();
//描画(原始图片)
canvas.drawBitmap(bitmap,0, 0, myPaint);
//新建颜色矩阵对象
myColorMatrix = new ColorMatrix();
//设置颜色矩阵的值
myColorMatrix.set(colorArray);
//设置画笔颜色过滤器
myPaint.setColorFilter(new ColorMatrixColorFilter(myColorMatrix));
//描画(处理后的图片)
canvas.drawBitmap(bitmap,0,0,myPaint);
invalidate();
}
//设置颜色数值
public void setColorArray(float[] colorArray){
this.colorArray = colorArray;
}
//设置图片
public void setBitmap(Bitmap bitmap){
this.bitmap = bitmap;
}
}
步骤二:自定义我们的布局
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/colorView_layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<com.mycolor.ColorView
android:id="@+id/myColorView"
android:layout_width="480dp"
android:layout_height="180dp"/>
<LinearLayout
android:id="@+id/colorlayout1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<EditText
android:id="@+id/Edit1"
android:layout_width="50dp"
android:layout_height="40dp"
android:layout_weight="1"
android:text="1" />
<EditText
android:id="@+id/Edit2"
android:layout_width="50dp"
android:layout_height="40dp"
android:layout_weight="1"
android:text="0"
/>
<EditText
android:id="@+id/Edit3"
android:layout_width="50dp"
android:layout_height="40dp"
android:layout_weight="1"
android:text="0" />
<EditText
android:id="@+id/Edit4"
android:layout_width="50dp"
android:layout_height="40dp"
android:layout_weight="1"
android:text="0" />
<EditText
android:id="@+id/Edit5"
android:layout_width="50dp"
android:layout_height="40dp"
android:layout_weight="1"
android:text="0" />
</LinearLayout>
<LinearLayout
android:id="@+id/colorlayout2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<EditText
android:id="@+id/Edit6"
android:layout_width="50dp"
android:layout_height="40dp"
android:layout_weight="1"
android:text="0" />
<EditText
android:id="@+id/Edit7"
android:layout_width="50dp"
android:layout_height="40dp"
android:layout_weight="1"
android:text="1" />
<EditText
android:id="@+id/Edit8"
android:layout_width="50dp"
android:layout_height="40dp"
android:layout_weight="1"
android:text="0" />
<EditText
android:id="@+id/Edit9"
android:layout_width="50dp"
android:layout_height="40dp"
android:layout_weight="1"
android:text="0" />
<EditText
android:id="@+id/Edit10"
android:layout_width="50dp"
android:layout_height="40dp"
android:layout_weight="1"
android:text="0" />
</LinearLayout>
<LinearLayout
android:id="@+id/colorlayout3"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<EditText
android:id="@+id/Edit11"
android:layout_width="50dp"
android:layout_height="40dp"
android:layout_weight="1"
android:text="0" />
<EditText
android:id="@+id/Edit12"
android:layout_width="50dp"
android:layout_height="40dp"
android:layout_weight="1"
android:text="0" />
<EditText
android:id="@+id/Edit13"
android:layout_width="50dp"
android:layout_height="40dp"
android:layout_weight="1"
android:text="1" />
<EditText
android:id="@+id/Edit14"
android:layout_width="50dp"
android:layout_height="40dp"
android:layout_weight="1"
android:text="0" />
<EditText
android:id="@+id/Edit15"
android:layout_width="50dp"
android:layout_height="40dp"
android:layout_weight="1"
android:text="0" />
</LinearLayout>
<LinearLayout
android:id="@+id/colorlayout4"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<EditText
android:id="@+id/Edit16"
android:layout_width="50dp"
android:layout_height="40dp"
android:layout_weight="1"
android:text="0" />
<EditText
android:id="@+id/Edit17"
android:layout_width="50dp"
android:layout_height="40dp"
android:layout_weight="1"
android:text="0" />
<EditText
android:id="@+id/Edit18"
android:layout_width="50dp"
android:layout_height="40dp"
android:layout_weight="1"
android:text="0" />
<EditText
android:id="@+id/Edit19"
android:layout_width="50dp"
android:layout_height="40dp"
android:layout_weight="1"
android:text="1" />
<EditText
android:id="@+id/Edit20"
android:layout_width="50dp"
android:layout_height="40dp"
android:layout_weight="1"
android:text="0" />
</LinearLayout>
<Button
android:id="@+id/Button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="0dp"
android:text="提交" />
</LinearLayout>
步骤三:完成我们的Activity
package com.mycolor;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
public class ColorActivity extends Activity implements OnClickListener{
private Button button = null;
private ColorView colorView = null;
private EditText[] editTextArray = null;
private float colorArray[] = null;
private int[] EditTextID = {R.id.Edit1,R.id.Edit2,R.id.Edit3,R.id.Edit4,R.id.Edit5,
R.id.Edit6,R.id.Edit7,R.id.Edit8,R.id.Edit9,R.id.Edit10,
R.id.Edit11,R.id.Edit12,R.id.Edit13,R.id.Edit14,R.id.Edit15,
R.id.Edit16,R.id.Edit17,R.id.Edit18,R.id.Edit19,R.id.Edit20};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
button = (Button)findViewById(R.id.Button);
button.setOnClickListener(this);
editTextArray = new EditText[20];
colorArray = new float[20];
for(int i = 0;i < 20;i++){
editTextArray[i] = (EditText)findViewById(EditTextID[i]);
}
colorView = (ColorView)findViewById(R.id.myColorView);
}
@Override
public void onClick(View v) {
for(int i = 0;i < 20;i++){
colorArray[i] = Float.valueOf(editTextArray[i].getText().toString().trim());
System.out.println("i = " + i + ":" + editTextArray[i].getText().toString().trim());
}
colorView.setColorArray(colorArray);
}
}
这样就可以了。
效果图:
改变值可以呈现不同的效果:
原文参考:点击打开链接
代码:点击下载