Android群英传--绘图机制与处理技巧(三)

Android中图像的色彩特效处理:

Android中色彩特效处理的基础:

Android中对于图片的处理通常使用的是Bitmap(位图),Bitmap中包含了一张图片的所有信息(点阵和颜色值)。点阵是一个包含像素的矩阵,每一个元素对应着图片的一个像素,而每一个像素都由一个颜色矩阵分量来保存该像素点的ARGB信息。颜色值——ARGB分别对应透明度,红色,绿色,蓝色,共同决定了像素点显示的颜色。

在Android中系统使用一个4x5的颜色矩阵(ColorMatrix)来处理图片的色彩效果(以一维数组的形式保存,a,b,c,d,e,f,g……r,s,t)。例如对于图片中的某一点像素,其颜色矩阵分量为C=????????RGBA1????????,而系统的颜色矩阵为A=?????afkpbglqchmrdinsejot?????,那么该像素点最终在屏幕上显示的颜色就是这两个矩阵乘积的结果,即该点最终显示在屏幕上的颜色为R=A?C=?????afkpbglqchmrdinsejot??????????????RGBA1????????=?????R1G1B1A1?????,其中R1=a?R+b?G+c?B+d?A+e?1,其他的G1,B1,A1也是矩阵的运算得出。该点最终显示的颜色就是矩阵R中的ARGB来共同决定的。通常情况下系统颜色矩阵为单位矩阵,即A=?????10000100001000010000?????

这就是Android中对图像的色彩处理的原理,而我们要做的就是通过修改颜色矩阵A来达到修改图片色彩的目的。



在图像处理中常见的三个名词的解释:

色调:色调不是指颜色的性质,而是对一幅绘画作品的整体颜色的概括评价。色调是指一幅作品色彩外观的基本倾向。在明度、纯度、色相这三个要素中,某种因素起主导作用,我们就称之为某种色调。一幅绘画作品虽然用了多种颜色,但总体有一种倾向,是偏兰或偏红,是偏暖或偏冷等等。这种颜色上的倾向就是一副绘画的色调。通常可以从色相、明度、冷暖、纯度四个方面来定义一幅作品的色调。

饱和度:饱和度是指色彩的鲜艳程度,也称色彩的纯度。饱和度取决于该色中含色成分和消色成分(灰色)的比例。含色成分越大,饱和度越大;消色成分越大,饱和度越小。纯的颜色都是高度饱和的,如鲜红,鲜绿;而白色,灰色等是不饱和的颜色。

亮度:亮度是指色彩的亮度或明度。颜色有深浅、明暗的变化。比如,深黄、中黄、淡黄、柠檬黄等黄颜色在明度上就不一样。



Android中色彩特效处理的途径:

知道了Android中色彩的处理办法和一些色彩名词,我们就可以尝试对图像的色彩进行处理了。根据我们前面知道的,色彩最终是由像素点的颜色矩阵和系统的ColorMatrix进行运算得到的。若是不对图片的色彩进行任何修改,则应该是R=A?C=?????10000100001000010000??????????????RGBA1????????=?????RGBA?????,这样图片不发生任何的变动。

由其运算规则可以知道,当我们需要修改RGBA时可以有两种方式:1>修改矩阵的偏移量2>修改矩阵的系数。这两种方式都能有效的改变最终色彩矩阵的值。

1>修改偏移量:

A=?????100001000010000110010000?????

图像的红色和绿色分量增加100,结果是色调更加偏向黄色(红色和绿色混合后得到黄色)

2>修改系数:

A=?????10000200001000010000?????

图像绿色分量的系数变为2,图像的色调更加偏向绿色。

3>使用系统提供的处理色光属性的方法:

  • 修改色调:
/*声明一个颜色矩阵*/
ColorMatrix hueMatrix = new ColorMatrix();
/*调用其setRotate()方法修改RGB的值*/
hueMatrix.setRotate(0,hue0);//用0,1,2来代表对R,G,B三色的处理

/** Set the rotation on a color axis by the specified values.

    * <code>axis=0</code> correspond to a rotation around the RED color
    * <code>axis=1</code> correspond to a rotation around the GREEN color
    * <code>axis=2</code> correspond to a rotation around the BLUE color

 **/
  • 修改饱和度:
//声明一个颜色矩阵
ColorMatrix saturationMatrix = new ColorMatrix();
调用其setSaturation()方法修改饱和度
saturationMatrix.setSaturation(saturation);//0代表灰度,1代表原图,比1越大的颜色越加饱和

/**sat A value of 0 maps the color to gray-scale. 1 is identity.**/
  • 修改亮度:
/**public void setScale (float rScale, float gScale, float bScale, float aScale)**/

//当三原色以相同的比例混合时就会出现白色,系统也正是通过这个原理改变亮度
ColorMatrix lumMatrix = new ColorMatrix();
lumMatrix.setScale(lum,lum,lum,1);
  • 组合效果:

系统提供了postConcat()方法来对多个矩阵进行计算

ColorMatrix imageMatrix = new ColorMatrix();
imageMatrix.postConcat(hueMatrix);
imageMatrix.postConcat(saturationMatrix);
imageMatrix.postConcat(lumMatrix);

这样就出来了组合效果。

对于这三种方式,其均不能对原图进行修改,而是要把原图复制一份,在副本上进行修改,完成后直接返回显示副本图片。所以我们在修改图片时要先根据原图来获得一个副本

//声明一个原图的副本
Bitmap resultBm = Bitmap.createBitmap(sourceBm.getWidth(), sourceBm.getHeight(), Bitmap.Config.ARGB_8888); 

Canvas canvas = new Canvas(resultBm);
Paint paint = new Paint();
//设置已经计算好的颜色矩阵
paint.setColorFilter(new ColorMatrixColorFilter(resultMatrix));
//绘制图片,之后若有需要可以把resultBm返回。
canvas.drawBitmap(sourceBm, 0, 0, paint);

源码下载:

图片处理demo



常用颜色矩阵:

  • 灰度效果:

    ?????0.33F0.33F0.33F00.59F0.59F0.59F00.11F0.11F0.11F000010000?????

  • 图像反转效果:

    ??????10000?10000?1011111110?????

  • 去色效果:

    ?????1.5F1.5F1.5F01.5F1.5F1.5F01.5F1.5F1.5F00001?1?1?10?????

在知道了这些图像处理的常见矩阵值之后我们就可以自己写出类似于图片处理软件中的各种滤镜效果了。O(∩_∩)O~



Android中对于像素点的处理:

之前都是对整个图像进行处理,所以常见的就是色调,饱和度,亮度的整体改变,但是有时候需要做更加精细的图像操作,Android中同样为我们提供了便捷的方法。

1.获取图片所有的像素点:

/** pixels  int[]-----接受回传的像素点数组,
    offset int-----读取的偏移量,
    stride int-----在pixels[]中的行间距
    x int-----从图片中读取像素点的x坐标
    y int-----从图片中读取像素点的y坐标
    width int-----每行读取的值
    height int------读取的行数
**/
 mBitmap.getPixels(pixels,offset ,stride,x,y, width, height); 

2.获取每个像素点的ARGB值:

for (int i = 0;i<width*height;i++) {
    color = oldPexil[i];
    //获取每个像素点的ARGB值
    r = Color.red(color);
    g = Color.green(color);
    b = Color.blue(color);
    a = Color.alpha(color);
}

3.对每个像素点进行处理:

for (int i = 0;i<width*height;i++) {
    color = oldPexil[i];
    //获取每个像素点的ARGB值
    r = Color.red(color);
    g = Color.green(color);
    b = Color.blue(color);
    a = Color.alpha(color);

    //对像素点进行处理
    r = (int) (0.393 * r + 0.769 * g + 0.189 * b);
    g = (int) (0.349 * r + 0.686 * g + 0.168 * b);
    b = (int) (0.272 * r + 0.543 * g + 0.131 * b);

    if (r > 255) {
       r = 255;
    }else if(r<0){
       r = 0;
    }
    if (g > 255) {
      g = 255;
    }else if(g<0){
      g = 0;
    }
   if (b > 255) {
      b = 255;
   }else if(b<0){
      b = 0;
   }
}

3.合成新的像素点数组并将其应用于图片:


for (int i = 0;i<width*height;i++) {
    color = oldPexil[i];
    //获取每个像素点的ARGB值
    r = Color.red(color);
    g = Color.green(color);
    b = Color.blue(color);
    a = Color.alpha(color);

    //对像素点进行处理
    r = (int) (0.393 * r + 0.769 * g + 0.189 * b);
    g = (int) (0.349 * r + 0.686 * g + 0.168 * b);
    b = (int) (0.272 * r + 0.543 * g + 0.131 * b);

    if (r > 255) {
       r = 255;
    }else if(r<0){
       r = 0;
    }
    if (g > 255) {
      g = 255;
    }else if(g<0){
      g = 0;
    }
   if (b > 255) {
      b = 255;
   }else if(b<0){
      b = 0;
   }
  //合成新的像素数组
  newPexil[i] = Color.argb(a, r, g, b);
}
//将新的像素数组应用于图像
bitmap.setPixels(newPexil, 0, width, 0, 0, width, height);

imageView.setImageBitmap(bitmap);

/**
    这里要注意bitmap是根据照片原图得到的一个副本。和之前一样,我们都无法对原图直接进行操作,返回的只是处理后的一个副本。
**/



附一个图像特效的处理库,十分强大,实现了PS中大部分的算法效果,Instagram、美图秀秀、美颜相机、Camera360大部分的滤镜特效。

博文地址

算法库下载地址

时间: 2024-10-11 00:33:20

Android群英传--绘图机制与处理技巧(三)的相关文章

Android群英传笔记——第七章:Android动画机制和使用技巧

Android群英传笔记--第七章:Android动画机制和使用技巧 想来,最近忙的不可开交,都把看书给冷落了,还有好几本没有看完呢,速度得加快了 今天看了第七章,Android动画效果一直是人家中十分重要的一部分,从早期的Android版本中,由于动画机制和绘图机制的不健全,Android的人机交互备受诟病,Android从4.X开始,特别是5.X,动画越来越完善了,Google也开始重视这一方面了,我们本章学习的主要内容有 Android视图动画' Android属性动画 Android动画

Android群英传笔记——第四章:ListView使用技巧

Android群英传笔记--第四章:ListView使用技巧 近期也是比較迷茫.可是有一点点还是要坚持的,就是学习了.近期离职了,今天也是继续温习第四章ListView,也拖了事实上也挺久的了,listview可谓是老牌大将了,非常多的应用场景都要使用它,他也是我们用得最多的控件之中的一个了,尽管如今出来了一个RecyclerView,可是ListView的地位一时半会儿还是撼动不了的.这就促使我们更加应该去把他掌握了 一.Listview经常使用优化技巧 我们一步步来把ListView学习好

ListView常用优化技巧(Android群英传)

内容是博主照着书敲出来的,博主码字挺辛苦的,转载请注明出处,后序内容陆续会码出. 前言:ListView--列表,它作为一个非常重要的显示方式,不管是在Web中还是移动平台中,都是一个非常好的.不开或缺的展示信息的工具.在Android中,ListView控件接管了这一重担,在大量的场合下,我们都需要使用这个控件.虽然在Android 5.X时代,RecyclerView在很多地方都在逐渐取代ListView,但ListView的使用范围依然非常的广泛,它这万年老大哥的地位也不是轻易就能撼动的.

Android群英传笔记——第九章:Android系统信息和安全机制

Android群英传笔记--第九章:Android系统信息和安全机制 本书也正式的进入尾声了,在android的世界了,不同的软件,硬件信息就像一个国家的经济水平,军事水平,不同的配置参数,代表着一个android帝国的强弱,所以厂商喜欢打配置战,本节就要是讲 Android系统信息的获取 PackageManager的使用 ActivityManager的使用 Android安全机制 一. Android系统信息的获取 由于android手机的开源性,手机的配置各种各样,那些优化大师之类的东西

事件拦截机制分析(Android群英传)

内容是博主照着书敲出来的,博主码字挺辛苦的,转载请注明出处,后序内容陆续会码出. 当Android系统捕获到用户的各种输入事件后,如何准确地传递给真正需要这个事件的控件呢?Android给我们提供了一整套完善的事件传递.处理机制,来帮助开发者完成准确的事件分配与处理. 要了解触摸事件的拦截机制,首先要了解什么是触摸事件?顾名思义,触摸事件就是捕获触摸屏幕后产生的事件.当点击一个按钮时,通常就会产生两个或者三个事件--按钮按下,这是事件一:如果不小心滑动一点,这就是事件二:当手抬起,这是事件三.A

Android群英传笔记——摘要,概述,新的出发点,温故而知新,能够为师矣!

Android群英传笔记--摘要.概述,新的出发点,温故而知新.能够为师矣! 当工作的越久,就越感到力不从心了,基础和理解才是最重要的,所以买了两本书,医生的<Android群英传>和主席的<Android开发艺术探索>.主要是再全面点的把自己所学的知识消化,这样也就不枉自己天天熬夜学习了,如今群英传快看完了.准备又一次再看一遍,同一时候把笔记以博客的形式记录下来,这样或许更加的深刻,然后再消磨一下主席的那本书,这本书有视频解说,更加好,所以估计以后应该非常少再写其它的博客,只是工

Android群英传-拼图游戏puzzle-代码设计和实现

上个周末,3个小时总体上读完了<Android群英传>,本周主要在研究代码层次的设计和实现.  编译安装在手机上,玩了几把,结合代码,一周时间才掌握了整体的思路.  大部分时间,其实花在了"重构"上.  重构的过程,就是学习和思考的过程.    本文,算是一篇学习总结,总体介绍下这款小游戏的实现思路.  后面抽空,再改造下这个游戏不合理的设计方式,即格子是N*N+1,而不是N*N个.    写到快吐了:在写过的几百篇文章里,其中有很多案例了,写得次数越多,越发现很多流程和思

Android群英传神兵利器读书笔记——第三章:Android Studio奇技淫巧

Android群英传神兵利器读书笔记--第三章:Android Studio奇技淫巧 这篇文章篇幅较长,可以使用版权声明下面的目录,找到感兴趣的进行阅读 目录 3.1 Android Studio使用初探 Project面板 Stucture面板 Android Monitor Keymap Tip of the Day 快速查找 Search Action 演示模式 3.2 Android Studio使用进阶 操作与导航 快速重构 代码模板 内置模板 自定义代码注释模板 代码分析 在Andr

自定义View(二)(Android群英传)

内容是博主照着书敲出来的,博主码字挺辛苦的,转载请注明出处,后序内容陆续会码出. 上一篇自定义View(一)(Android群英传)中说的是对现有控件进行拓展,这篇介绍第二种自定义View方法,创建复合控件. 创建复合控件 创建复合控件可以很好地创建出具有重用功能的控件集合.这种方式通常需要继承一个合适的ViewGroup,再给它添加指定功能的控件,从而组合成新的复合控件.通过这种方式创建的控件,我们一般会给它指定一些可配置的属性,让它具有更强的拓展性.下面就以一个TopBar为示例,讲解如何创