通过前面的分析,我们知道了调整颜色矩阵可以改变一副图像的色彩效果,图像处理很大程度上就是在寻找处理图像的颜色矩阵。不仅仅可以通过Android系统提供的API来进行ColorMatrix的修改,同样可以精确地修改矩阵的值来实现颜色效果的处理。
下面我们就模拟一个4*5的颜色矩阵。通过修改矩阵中的值,一来验证全面所说的改变图像色彩效果的原理是否正确,二来对矩阵变换产生的作用效果有更清晰地认识。程序运行后的效果如图(1)所示。
图(1) 模拟颜色矩阵
程序的难点在于创建下面的4*5的矩阵,通过GridLayout来进行布局,动态添加20个EditText,布局代码如下所示。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<ImageView
android:id="@+id/imageview"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2">
</ImageView>
<GridLayout
android:id="@+id/group"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="3"
android:columnCount="5"
android:rowCount="4"
>
</GridLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="btnChange"
android:text="Change"
></Button>
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="btnReset"
android:text="Reset"
></Button>
</LinearLayout>
</LinearLayout>
动态创建EditText,添加到GridLayout并初始化矩阵的代码如下所示。
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ysjz);
bitmap = ((BitmapDrawable)getResources().getDrawable(R.mipmap.asdfasdf)).getBitmap();
mImageView = findViewById(R.id.imageview);
mGroup = findViewById(R.id.group);
mImageView.setImageBitmap(bitmap);
mGroup.post(new Runnable() {
@Override
public void run() {
//获取宽高信息
mEtWidth = mGroup.getWidth()/5;
mEtHeight = mGroup.getHeight()/4;
addEts();
initMatrix();
}
});
}
private void addEts(){
for (int i = 0;i<20;i++){
EditText editText = new EditText(this);
mEts[i] = editText;
mGroup.addView(editText,mEtWidth,mEtHeight);
}
}
private void initMatrix(){
for (int i = 0;i<20;i++){
if (i%6==0){
mEts[i].setText(String.valueOf(1));
}else {
mEts[i].setText(String.valueOf(0));
}
}
}
需要注意的是,我们无法在onCreate()方法中获取视图的宽高值,所有通过通过View的post方法,在视图创建完毕后获得其宽高值。
接下来,只需要获得修改后的EditText的值,并将矩阵值设置给颜色矩阵即可。在Android程序中,使用一个一维数组来保存20个矩阵值,并通过ColorMartix的set方法,将一个一维数组转化为ColorMatrix,代码如下所示。
//获取矩阵值
private void getMatrix(){
for(int i = 0;i<20;i++){
mColoMatrix[i] = Float.valueOf(mEts[i].getText().toString());
}
}
//将矩阵值设置到图像
private void setImageMatrix(){
Bitmap bmp = Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(),Bitmap.Config.ARGB_8888);
ColorMatrix colorMatrix = new ColorMatrix();
colorMatrix.set(mColoMatrix);
Canvas canvas = new Canvas(bmp);
Paint paint = new Paint();
paint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
canvas.drawBitmap(bitmap,0,0,paint);
mImageView.setImageBitmap(bmp);
}
最后,设置好两个按钮的点击事件即可,一个是将现有矩阵作用到图像,另一个是将现有矩阵恢复到初始矩阵状态。再作用到图像,即还原图像,代码如下所示。
//作用矩阵效果
public void btnChange(View view){
getMatrix();
setImageMatrix();
}
//重置矩阵效果
public void btnReset(View view){
initMatrix();
getMatrix();
setImageMatrix();
}
程序运行效果如图(2)、图(3)所示,可以利用这个模拟矩阵来验证一下前面颜色矩阵伦理分析,分别设置偏移量和系数,来看看是否与预期效果相同。
图(2) 改变颜色偏移
图(3) 改变颜色系数