该类内部引用的有一个ColorMatrix对象,它的主要工作也是通过ColorMatrix完成的。而且主要工作原理也可以看ColorMatrix类的注释。示例如下:
protected void onDraw(Canvas canvas) { super.onDraw(canvas); Paint paint = mPaint; float x = 20; float y = 20; canvas.drawColor(Color.WHITE); paint.setColorFilter(null); ColorMatrix cm = new ColorMatrix(); mAngle += 2; if (mAngle > 180) { mAngle = 0; } float contrast = mAngle / 180.f; setContrast(cm, contrast); paint.setColorFilter(new ColorMatrixColorFilter(cm)); canvas.drawBitmap(mDrawable, x + mDrawable.getWidth() + 10, y, paint); invalidate(); } private void setContrast(ColorMatrix cm, float contrast) { //会不断地将rgb的值变大,从而导致图片越来越趋向白色(感觉越来越亮)。 float scale = contrast + 1.f; float translate = (-.5f * scale + .5f) * 255.f; cm.set(new float[] { scale, 0, 0, 0, translate, 0, scale, 0, 0, translate, 0, 0, scale, 0, translate, 0, 0, 0, 1, 0 }); }
在new 对象时需要传入两个int类型,那么每一个像素点的颜色变化是:该像素点的颜色乘以第一个参数上的相应颜色,再加上第二个参数上的相应颜色,也就是说:原像素的红色值&第一个参数的红色值|第二个参数的红色值,得到的是新颜色中的红色值。以些类推,直到得到r,g,b三种颜色的值。
英文文档说明:Create a colorfilter that multiplies the RGB channels by one color, and then adds a second color,pinning the result for each component to [0..255].The alpha components of the mul and add arguments are ignored(不考虑透明度的变化)。
验证如下:
//675433 int red = Color.red(Color.rgb(0x67, 0x54, 0x33)) & Color.red(Color.rgb(0xff, 0, 0)) | Color.red(Color.rgb(0x00, 0x00, 0xff));//取red值 int g = Color.green(Color.rgb(0x67, 0x54, 0x33)) & Color.green(Color.rgb(0xff, 0, 0)) | Color.green(Color.rgb(0x00, 0x00, 0xff)); int b = Color.blue(Color.rgb(0x67, 0x54, 0x33)) & Color.blue(Color.rgb(0xff, 0, 0)) | Color.blue(Color.rgb(0x00, 0x00, 0xff)); Log.e("TAG", Integer.toHexString(bitmap.getPixel(10, 10)) + "---" +Integer.toHexString(bitmap1.getPixel(10, 10)) + "---" + Integer.toHexString(Color.rgb(red, g, b)));其中输出的log中,第一个为原图中的颜色值(原图为一个纯色图片0x675433),第二个为改变后的颜色值(为6700ff),第三个为自己计算输出的结果(6700ff)。其中的filter如下:
LightingColorFilter filter = new LightingColorFilter(Color.rgb(0xff, 0, 0), 0x0000ff);
内部怎么更改的不明。第二个参数也是上面的PorterDuff.Mode中的值。并且src代表的是new PorterDuffColorFilter时传入的第一个参数。
由于Mode中有一些值是用于处理图片相交时的效果的,因此将这些值设置到ColorFilter时不会产生任何效果。具体哪些值不明。
虽然它是一个1*20的行向量,但在实际用的时候要理解为4*5的矩阵,如下图:
在实际使用中的每一个像素点都是以5*1的列向量表示的(元素从上往下依次表示r,g,b,a,1)。因此使用ColorMatrix时,就相当于4*5的矩阵右乘5*1的列向量(filter*color),得到的是4*1的列向量。而且该列向量的值从上往下分别表示r,g,b,a,即某一像素处的新颜色值。