Paint,ColorMatrix(颜色矩阵)实现滤镜效果及矩阵运算

滤镜效果:


颜色通道

每个图像都有一个或多个颜色通道,图像中默认的颜色通道数取决于其颜色模式,即一个图像的颜色模式将决定其颜色通道的数量。例如,CMYK图像默认有4个通道,分别为青色、洋红、黄色、黑色。在默认情况下,位图模式、灰度、双色调和 索引颜色图像只有一个通道。RGB和Lab图像有3个通道,CMYK图像有4个通道。
每个颜色通道都存放着图像中颜色元素的信息。所有颜色通道中的颜色叠加混合产生图像中像素的颜色。
为了便于理解通道的概念,我们以RGB模式图像为例,简单介绍颜色通道原理


颜色模式

颜色模式:颜色模式我门可以理解为将某种颜色表现为数字形式的模型,或者说是一种记录图像颜色的方式。分为:RGB模式、CMYK模式、HSB模式、Lab颜色模式、位图模式、灰度模式、索引颜色模式、双色调模式和多通道模式等。
其实实际上我们就认为,现在我要显示的色彩这个时候是用数字表示,最经典的RGB模式我们可以理解为R(255) G(0) B(0)当前这个像素,显示,在识别的时候为红色,他由红 绿 蓝 三种色彩进行混合,显示出我们要的颜色其程度数值是0-255的范围

总结:也就是说,其实图像的显示,每个点都是由模式所决定的色彩数值混合形成我们想要的颜色,那么我们的滤镜效果实现,其实实际上就是去对于颜色通道进行过滤操作,在其原本的模式数值上面进行操作,达到更改图像色彩效果的目的,这就是我们所为的滤镜


各种模式的定义

RGB颜色模式

虽然可见光的波长有一定的范围,但我们在处理颜色时并不需要将每一种波长的颜色都单独表示。因为自然界中所有的颜色都可以用红、绿、蓝(RGB)这三种颜色波长的不同强度组合而得,这就是人们常说的 三基色原理。因此,这三种光常被人们称为三基色或三原色。有时候我们亦称这三种基色为添加色(Additive Colors),这是因为当我们把不同光的波长加到一起的时候,得到的将会是更加明亮的颜色。把三种基色交互重叠,就产生了次混合色:青(Cyan)、洋红(Magenta)、黄(Yellow)。这同时也引出了互补色(Complement Colors)的概念。基色和次混合色是彼此的互补色,即彼此之间最不一样的颜色。例如青色由蓝色和绿色构成,而红色是缺少的一种颜色,因此青色和红色构成了彼此的互补色。在数字视频中,对RGB三基色各进行8位编码就构成了大约1677万种颜色,这就是我们常说的真彩色。顺便提一句,电视机和计算机的监视器都是基于RGB颜色模式来创建其颜色的

CMYK模式

CMYK颜色模式是一种印刷模式。其中四个字母分别指青(Cyan)、洋红(Magenta)、黄(Yellow)、黑(Black),在印刷中代表四种颜色的油墨。CMYK模式在本质上与RGB模式没有什么区别,只是产生色彩的原理不同,在RGB模式中由光源发出的色光混合生成颜色,而在CMYK模式中由光线照到有不同比例C、M、Y、K油墨的纸上,部分光谱被吸收后,反射到人眼的光产生颜色。由于C、M、Y、K在混合成色时,随着C、M、Y、K四种成分的增多,反射到人眼的光会越来越少,光线的亮度会越来越低,所有CMYK模式产生颜色的方法又被称为色光减色法。

HSB颜色模式

从心理学的角度来看,颜色有三个要素:色泽(Hue)、饱和度(Saturation)和亮度(Brightness)。HSB颜色模式便是基于人对颜色的心理感受的一种颜色模式。它是由RGB三基色转换为Lab模式,再在Lab模式的基础上考虑了人对颜色的心理感受这一因素而转换成的。因此这种颜色模式比较符合人的视觉感受,让人觉得更加直观一些。它可由底与底对接的两个圆锥体立体模型来表示,其中轴向表示亮度,自上而下由白变黑;径向表示色饱和度,自内向外逐渐变高;而圆周方向,则表示色调的变化,形成色环 .。

Lab颜色模式

Lab颜色是由RGB三基色转换而来的,它是由RGB模式转换为HSB模式和CMYK模式的桥梁。该颜色模式由一个发光率(Luminance)和两个颜色(a,b)轴组成。它由颜色轴所构成的平面上的环形线来表示色的变化,其中径向表示色饱和度的变化,自内向外,饱和度逐渐增高;圆周方向表示色调的变化,每个圆周形成一个色环;而不同的发光率表示不同的亮度并对应不同环形颜色变化线。它是一种具有“独立于设备”的颜色模式,即不论使用任何一种监视器或者打印机,Lab的颜色不变。其中a表示从洋红至绿色的范围,b表示黄色至蓝色的范围

位图模式

位图模式用两种颜色(黑和白)来表示图像中的像素。位图模式的图像也叫作黑白图像。因为其深度为1,也称为一位图像。由于位图模式只用黑白色来表示图像的像素,在将图像转换为位图模式时会丢失大量细节,因此Photoshop提供了几种算法来模拟图像中丢失的细节。 在宽度、高度和分辨率相同的情况下,位图模式的图像尺寸最小,约为灰度模式的1/7和RGB模式的1/22以下。

灰度模式

灰度模式可以使用多达256级灰度来表现图像,使图像的过渡更平滑细腻。灰度图像的每个像素有一个0(黑色)到255(白色)之间的亮度值。灰度值也可以用黑色油墨覆盖的百分比来表示(0%等于白色,100%等于黑色)。使用黑折或灰度扫描仪产生的图像常以灰度显示。

扫描二维码关注公众号,回复: 1890187 查看本文章

索引颜色模式

索引颜色模式是网上和动画中常用的图像模式,当彩色图像转换为索引颜色的图像后包含近256种颜色。索引颜色图像包含一个颜色表。如果原图像中颜色不能用256色表现,则Photoshop会从可使用的颜色中选出最相近颜色来模拟这些颜色,这样可以减小图像文件的尺寸。用来存放图像中的颜色并为这些颜色建立颜色索引,颜色表可在转换的过程中定义或在生成索引图像后修改。

双色调模式

双色调模式采用2-4种彩色油墨来创建由双色调(2种颜色)、三色调(3种颜色)和四色调(4种颜色)混合其色阶来组成图像。在将 灰度图像转换为双色调模式的过程中,可以对色调进行编辑,产生特殊的效果。而使用双色调模式最主要的用途是使用尽量少的颜色表现尽量多的颜色层次,这对于减少印刷成本是很重要的,因为在印刷时,每增加一种色调都需要更大的成本。

多通道模式

多通道模式对有特殊打印要求的图像非常有用。例如,如果图像中只使用了一两种或两三种颜色时,使用多通道模式可以减少印刷成本并保证图像颜色的正确输出。 6. 8位/16位通道模式 在灰度RGB或CMYK模式下,可以使用16位通道来代替默认的8位通道。根据默认情况,8位通道中包含256个 色阶,如果增到16位,每个通道的色阶数量为65536个,这样能得到更多的色彩细节。Photoshop可以识别和输入16位通道的图像,但对于这种图像限制很多,所有的滤镜都不能使用,另外16位通道模式的图像不能被印刷。
总结:也就是说,其实图像的显示,每个点都是由模式所决定的色彩数值混合形成我们想要的颜色,那么我们的滤镜效果实现,其实实际上就是去对于颜色通道进行过滤操作,在其原本的模式数值上面进行操作,达到更改图像色彩效果的目的,这就是我们所为的滤镜


颜色矩阵:ColorMatrix
 
 

在android当中,他所采用的颜色模式是RGBA模式,也就是在红绿蓝的基础上加入了Alpha透明度的概念,那么也就是他现在是一个四通道的模式。下来我们看一下ColorMatrix定义,如下:

ColorMatrix源码定义
/**
 * 4x5 matrix for transforming the color and alpha components of a Bitmap.
 * The matrix can be passed as single array, and is treated as follows:
 *用于转换位图的颜色和alpha组成的4x5矩阵。
 矩阵可以作为单个数组传递,并按照以下方式进行处理
 * <pre>
 *  [ a, b, c, d, e,
 *    f, g, h, i, j,
 *    k, l, m, n, o,
 *    p, q, r, s, t ]</pre>
 *
 * <p>
 * When applied to a color <code>[R, G, B, A]</code>, the resulting color
 * is computed as:
 *当应用到一种颜色的时候,它的颜色是R,G,B,A
 *计算为:
 * </p>
 *
 * <pre>
 *   R&rsquo; = a*R + b*G + c*B + d*A + e;
 *   G&rsquo; = f*R + g*G + h*B + i*A + j;
 *   B&rsquo; = k*R + l*G + m*B + n*A + o;
 *   A&rsquo; = p*R + q*G + r*B + s*A + t;</pre>
 *
 * <p>
 * That resulting color <code>[R&rsquo;, G&rsquo;, B&rsquo;, A&rsquo;]</code>
 * then has each channel clamped to the <code>0</code> to <code>255</code>
 * range.
 * </p>
 *产生的颜色是R'G'B',A'/码
 然后每个频道都被夹在“0”到“255”的代码中范围
 *
 * <p>
 * The sample ColorMatrix below inverts incoming colors by scaling each
 * channel by <code>-1</code>, and then shifting the result up by
 * <code>255</code> to remain in the standard color space.
 * </p>
 *
 * <pre>
 *   [ -1, 0, 0, 0, 255,
 *     0, -1, 0, 0, 255,
 *     0, 0, -1, 0, 255,
 *     0, 0, 0, 1, 0 ]</pre>
 */

在Android中图片是以RGBA像素点的形式加载到内存中的,修改这些像素信息需要一个叫做ColorMatrix类的支持。ColorMatrix就是Android系统使用的色彩矩阵。

Android中的颜色矩阵是一个4×5的数字矩阵:

在Android中他会以一维数组的形式来存储:(float[]类型)

[ a, b, c, d, e,f, g, h, i, j,k, l, m, n, o,p, q, r, s, t ]

一般我们为了可读性,我们会写得好看些:

?
new float[]{
        a, b, c, d, e,
                f, g, h, i, j,
                k, l, m, n, o,
                p, q, r, s, t
    }

那这个矩阵该怎么使用呢?其实就是使用矩阵乘法运算。

这里有一个色彩矩阵分量C,代表着我们要进行色彩变化的原色彩。

矩阵R则代表通过矩阵乘法运算AC而得到的新的颜色。

通过矩阵乘法可知:

通过这个公式我们就可以得出我们的色彩矩阵A的意义:

第一行的abcde值用来决定新的颜色值中的R 第二行的fghij值用来决定新的颜色值中的G 第三行的klmno值用来决定新的颜色值中的B 第四行的pqrdt值用来决定新的颜色值中的A 其中第五列ejot值分别用来决定每个分量重的offset,即偏移量

颜色矩阵改变颜色值

使用色彩矩阵改变颜色值一般有三种方法:
1. 直接改变色彩矩阵的offset偏移量
2. 直接改变对应RGBA值的系数
3. 使用封装好的API来改变参数


具体应用实现


1.申明初始化
Paint paint;
Bitmap bitmap;
private void init() {
    paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    paint.setColor(Color.RED);
    bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.timg);//获取要给做滤镜效果的图片
}



onDraw


rets = new Rect("","","","")//确定绘制形状

canvas.drawBitmap(bitmap,null, 
rets ,paint);

paint.reset();
paint.setColor(Color.RED);

    //颜色矩阵

ColorMatrix colorMartrix = new ColorMatrix(new float[]{
        1,0,0,0,10,
        0, 0,0,0,10,
        0,0,0,0,0,
        0,0,0,0.5F,10,
});


Rect rect1 = new Rect(50,20 + bitmap.getHeight(),bitmap.getWidth()+100,bitmap.getHeight() * 2);
paint.setColorFilter(new ColorMatrixColorFilter(colorMartrix));
canvas.drawBitmap(bitmap,null, rect1,paint);

 
 
调用
//滤镜
setContentView(new FilterView(this));

反转
ColorMatrix colorMartrix = new ColorMatrix(new float[]{
        -1, 0, 0, 0, 255,
        0, -1, 0, 0, 255,
        0, 0, -1, 0, 255,
        0, 0, 0, 1, 0
});
                                原图                                                                                  反转



复古
ColorMatrix colorMartrix = new ColorMatrix(new float[]{
        1/2f,1/2f,1/2f,0,0,
        1/3f, 1/3f,1/3f,0,0,
        1/4f,1/4f,1/4f,0,0,
        0,0,0,1,0,
});

猜你喜欢

转载自blog.csdn.net/u014133119/article/details/80762331
今日推荐