一、简介

setColorFilter(ColorFilter filter)

设置颜色过滤,这个方法需要我们传入一个ColorFilter参数同样也会返回一个ColorFilter实例。我们在setColorFilter(ColorFilter filter)的时候可以直接传入ColorMatrixColorFilter、LightingColorFilter或PorterDuffColorFilter的子类对象作为参数。这些类其实都是colorFilter的子类,下面我们来一个个分析下它们的作用。

二、ColorMatrixColorFilter

中文直译为“色彩矩阵颜色过滤器”,我们要先了解什么是色彩矩阵。在Android中图片是以RGBA像素点的形式加载到内存中的,修改这些像素信息需要一个叫做ColorMatrix类的支持,这个类其实定义的是一个矩阵,是一个4x5的float[]类型的矩阵:

ColorMatrix colorMatrix = new ColorMatrix(new float[]{
1, 0, 0, 0, 0, // 红色向量
0, 1, 0, 0, 0, // 绿色向量
0, 0, 1, 0, 0, // 蓝色向量
0, 0, 0, 1, 0, // 透明度向量
});

其中,第一行表示的R(红色)的向量,第二行表示的G(绿色)的向量,第三行表示的B(蓝色)的向量,最后一行表示A(透明度)的向量,这一顺序必须要正确不能混淆!你可能会问,那么列呢?我用图例来表示一下。

  

  这个矩阵不同的位置表示的R、G、B、A值,其范围在0.0F至2.0F之间,1为保持原图的RGB值。每一行的第五列数字表示”偏移值“。

  何为偏移值?顾名思义当我们想让颜色更倾向于红色的时候就增大R向量中的偏移值,想让颜色更倾向于蓝色的时候就增大B向量中的偏移值,这是最最朴素的理解,但是事实上色彩偏移的概念是基于白平衡来理解的。

  什么是白平衡呢?说得简单点就是白色是什么颜色!在单反的设置参数中有个色彩偏移,其定义的就是白平衡的色彩偏移值,就是当你去拍一张照片的时候白色是什么颜色的,在正常情况下白色是(255, 255, 255, 255)但是“现实世界中我们是无法找到这样的纯白物体的”,所以在我们用单反拍照之前就会拿一个我们认为是白色的物体让相机记录这个物体的颜色作为白色,然后拍摄时整张照片的颜色都会依据这个定义的白色来偏移!而这个我们定义的“白色”(比如:255, 253, 251, 247)和纯白(255, 255, 255, 255)之间的偏移值(0, 2, 4, 8)我们称之为白平衡的色彩偏移。

测试一下:

我们想要绘制一个橙色的圆圈,橙色的效果如下:

我们建立一个矩阵,然后看看效果。

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas); // 生成色彩矩阵
ColorMatrix colorMatrix = new ColorMatrix(new float[]{
1, 0, 0, 0, 0,
0, 1, 0, 0, 0,
0, 0, 1, 0, 0,
0, 0, 0, 1, 0,
});
mPaint.setColorFilter(new ColorMatrixColorFilter(colorMatrix)); // 设置画笔颜色为自定义颜色
mPaint.setColor(Color.argb(255, 255, 128, 103)); // 绘制圆环 (x坐标,y坐标,半径,画笔)
canvas.drawCircle(240, 600 / 2, 200, mPaint);
}

看看效果:

你会发现颜色没有任何变化,为什么呢?因为矩阵的1表示不做任何变化,也就是保持原样。我们换一个下面的矩阵就能看到效果了。

说明:如果在eclipse实时预览的话,它会提示说如果你设置了这个属性,那么eclipse可能无法准确的给你一个预览图。别担心,实际运行的时候就出来了。

     // 生成色彩矩阵
ColorMatrix colorMatrix = new ColorMatrix(new float[]{
0.5F, 0, 0, 0, 0,
0, 0.5F, 0, 0, 0,
0, 0, 0.5F, 0, 0,
0, 0, 0, 1, 0,
});

我们来看看这个矩阵是怎么计算的。其实说白了就是矩阵之间的运算乘积:

矩阵ColorMatrix的一行乘以矩阵MyColor的一列作为矩阵Result的一行,这里MyColor的RGBA值我们需要转换为[0, 1]。通过这种计算我们可以将我们自己设定的颜色和矩阵的颜色进行叠加,创立一个新的颜色。

再测试一下:

如果我们用它来给图片改颜色,该怎么做呢?下面的例子将会演示一下。

原本图片:

加上滤镜后:

    @Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas); // 生成色彩矩阵
ColorMatrix colorMatrix = new ColorMatrix(new float[]{
-1, 0, 0, 1, 1,
0, -1, 0, 1, 1,
0, 0, -1, 1, 1,
0, 0, 0, 1, 0,
});
mPaint.setColorFilter(new ColorMatrixColorFilter(colorMatrix)); Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.kale);
canvas.drawBitmap(bitmap,240,600,mPaint);
}

这说明,我们可以通过设置滤镜来设置bitmap。如果想要看更多的效果,可以去:http://blog.csdn.net/aigestudio/article/details/41316141 看看。

现在我们知道了,ColorMatrixColorFilter和ColorMatrix就是这么个东西,ColorMatrix类里面也提供了一些实在的方法,比如setSaturation(float sat)设置饱和度,而且ColorMatrix每个方法都用了阵列的计算,如果大家感兴趣可以自己去深挖。

三、LightingColorFilter

顾名思义光照颜色过滤,这肯定是跟光照是有关的了。该类有且只有一个构造方法:

LightingColorFilter (int mul, int add)  

mul全称是colorMultiply意为色彩倍增,而add全称是colorAdd意为色彩添加,这两个值都是16进制的色彩值0xAARRGGBB。这个方法使用也是非常的简单。还是拿上面那张图片来说吧,比如我们想要去掉绿色:

    @Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas); // 设置颜色过滤
mPaint.setColorFilter(new LightingColorFilter(0xFFFF00FF, 0x00000000)); Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.kale);
canvas.drawBitmap(bitmap,240,600,mPaint);
}

运行后你会发现绿色确实是没了但是原来偏绿的部分现在居然成了红色,当LightingColorFilter(0xFFFFFFFF, 0x00000000)的时候原图是不会有任何改变的,如果我们想增加红色的值,那么LightingColorFilter(0xFFFFFFFF, 0x00XX0000)就好,其中XX取值为00至FF。

四、PorterDuffColorFilter

PorterDuffColorFilter跟LightingColorFilter一样,只有一个构造方法:

PorterDuffColorFilter(int color, PorterDuff.Mode mode)  

这个构造方法也接受两个值,一个是16进制表示的颜色值这个很好理解,而另一个是PorterDuff内部类Mode中的一个常量值,这个值表示混合模式。那么什么是混合模式呢?混合混合必定是有两种东西混才行,第一种就是我们设置的color值而第二种当然就是我们画布上的元素了!也就是说将画布上的元素和我们设置的color进行混合,产生最终的效果。

你可以类比为PS中的混合模式,只是PS的图层混合模式比Android更多更广泛,但两者同名混合模式所产生的效果是一样的,也基于同样的算法原理这里就不多说了。

    @Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas); // 设置颜色过滤
mPaint.setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.DARKEN)); Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.kale);
canvas.drawBitmap(bitmap,240,600,mPaint);
}

但是这里要注意一点,PorterDuff.Mode中的模式不仅仅是应用于图像色彩混合,还应用于图形混合,比如PorterDuff.Mode.DST_OUT就表示裁剪混合图。

参考自:

http://blog.csdn.net/aigestudio/article/details/41316141

http://blog.csdn.net/xanxus46/article/details/7883554

From AigeStudio(http://blog.csdn.net/aigestudio)Power by Aige  尊重原作者,感谢作者的分享!

详解Paint的setColorFilter(ColorFilter filter)的更多相关文章

  1. 详解Paint的各种set方法

    一.前言 我们用set方法来设置画笔的样式,类似于我们挑选画笔画画的过程.由于上面有些方法不支持硬件加速,所以在高版本系统中可能会没有效果.因此,我们首先来看看官方废弃的方法. 下图来自:https: ...

  2. 详解Paint的setXfermode(Xfermode xfermode)

    一.setXfermode(Xfermode xfermode) Xfermode国外有大神称之为过渡模式,这种翻译比较贴切但恐怕不易理解,大家也可以直接称之为图像混合模式,因为所谓的“过渡”其实就是 ...

  3. Logstash组件详解(input、codec、filter、output)

    logstash组件详解 logstash的概念及特点. 概念:logstash是一个数据采集.加工处理以及传输(输出)的工具. 特点: - 所有类型的数据集中处理 - 不同模式和格式数据的正常化 - ...

  4. 详解Paint的setPathEffect(PathEffect effect)

    一.setPathEffect() 这个方法一看就和path有关,顾名思义,它就是给path设置样式(效果)的.PathEffect这个路径效果类没有具体的实现,效果是由它的六个子类实现的: 这六个子 ...

  5. 详解Paint的setMaskFilter(MaskFilter maskfilter)

    一.setMaskFilter(MaskFilter maskfilter) setMaskFilter(MaskFilter maskfilter)是paint中的方法,它可以用来对图像进行一定的处 ...

  6. HTMLParser使用详解(3)- 通过Filter访问内容

    HTMLParser遍历了网页的内容以后,以树(森林)结构保存了结果.HTMLParser访问结果内容的方法有两种.使用Filter和使用Visitor. (一)Filter类顾名思义,Filter就 ...

  7. Web.xml详解(转)(Filter,context,listener)

    web.xml 详细解释!!(链接) web.xml加载过程(步骤) 首先简单说一下,web.xml的加载过程. 当我们去启动一个WEB项目时,容器包括(JBoss.Tomcat等)首先会读取项目we ...

  8. 详解Paint的setShader(Shader shader)

    一.概述 setShader(Shader shader)中传入的自然是shader对象了,shader类是Android在图形变换中非常重要的一个类.Shader在三维软件中我们称之为着色器,其作用 ...

  9. 转载爱哥自定义View系列--Paint详解

    上图是paint中的各种set方法 这些属性大多我们都可以见名知意,很好理解,即便如此,哥还是带大家过一遍逐个剖析其用法,其中会不定穿插各种绘图类比如Canvas.Xfermode.ColorFilt ...

随机推荐

  1. oracle中REGEXP_SUBSTR方法的使用

    近期在做商旅机票平台,遇到这样一个问题: 有一张tt_ticket表,用来存机票信息.里边有一个字段叫schedule,表示的是行程,存储格式为:北京/虹桥 由于公司位于上海.而上海眼下有两个机场:浦 ...

  2. OCM_第二十天课程:Section9 —》Data Guard _ DATA GUARD 搭建/DATA GUARD 管理

    注:本文为原著(其内容来自 腾科教育培训课堂).阅读本文注意事项如下: 1:所有文章的转载请标注本文出处. 2:本文非本人不得用于商业用途.违者将承当相应法律责任. 3:该系列文章目录列表: 一:&l ...

  3. Mac下brew安装与配置mysql

    一.打开mac控制台 $ brew install mysql 二.启动mysql服务 $ mysql.server start 三.初始化mysql配置 1 rainMacBook-Pro:~ co ...

  4. 基于struts研究传值问题

    一.新建项目 struts 1.file——>new——>Web Project——>取名struts——>finsh——>将之前项目下的jar包copy到该项目下 2. ...

  5. Ext.js中自己扩展的EasyGrid

    这里只写了一些核心的代码,具体如下: Ext.ux.EasyGrid = Ext.extend(Ext.grid.GridPanel, { initComponent: function () { t ...

  6. Ext.js入门

    一:ExtJs简介: ExtJs通常简称为Ext,它是一个非常优秀的Ajax框架,用Javascript编写,它与后台技术无关,可以用来开发具有炫丽外观的富客户端应用.Ext所开发的多彩界面吸引了许多 ...

  7. 浅析微信支付:微信支付简单介绍(小程序、公众号、App、H5)

    本文是[浅析微信支付]系列文章的第二篇,主要讲解一下普通商户接入的支付方式以及其中的不同之处. 上篇文章讲了本系列的大纲,没有看过的朋友们可以看一下. 浅析微信支付:前篇大纲 微信支付是集成在微信客户 ...

  8. [转]oracle10客户端PL/SQL Developer如何连接远程服务器上的oracle数据库

    时间:2013年8月21日 前提条件:假设你已经安装好了oracle和PL/SQL Developer,知道远程服务器的IP和数据库端口,知道远程服务器上的oracle数据库名和密码 如何用PL/SQ ...

  9. python常用内建模块--datetime

    datetime模块中的datetime类: 获取当前时间:datetime.now() 当前操作系统时区时间,date.utctime(UTC时间) 转换成时间戳:timestamp() 和具体时区 ...

  10. P1541 乌龟棋 线性dp

    题目背景 小明过生日的时候,爸爸送给他一副乌龟棋当作礼物. 题目描述 乌龟棋的棋盘是一行NN个格子,每个格子上一个分数(非负整数).棋盘第1格是唯一的起点,第NN格是终点,游戏要求玩家控制一个乌龟棋子 ...