zoukankan      html  css  js  c++  java
  • 【转】图片处理:颜色矩阵和坐标变换矩阵

    转载自ian的个人博客[http://www.icodelogic.com]
    本文链接地址: http://www.icodelogic.com/?p=559

    UI开发过程中,我们经常需要对图片进行处理,常见的如贴图,复杂一些的还有位置变换、旋转、滤镜特效等,下面简单介绍一下关于图片处理的一些基本知识和原理。

    1 基本概念
    对于图片的处理,最常使用到的数据结构是Bitmap,它包含了一张图片所有的数据,这些数据数据包括那些内容呢?简单说来就是由点阵和颜色值组成的,所谓点阵就是一个在概念上是Width * Height的矩阵,每一个元素对应着图片的一个像素,也就是说,点阵保存着图片的空间位置信息;而颜色值即ARGB,分别对应透明度、红、绿、蓝这四个通道分量,每个通道用8比特定义,所以一个颜色值就是一个int整型,可以表示256*256*256种颜色值。

    Android中我们常用到这么几个常量:ARGB_8888、ARGB_4444、RGB_565。这几个常量其实就是告诉系统如何对图片的颜色值进行处理,例如ARGB_8888是告诉系统透明度、R、G、B在颜色值中分别用8bit表示,这时颜色值为32bit,这样的定义能够表示最多的颜色值,图片质量也是最好的;ARGB_4444则是每个通道用4bit表示,这样颜色值只用16bit,节省了空间,但是却只能表示16*16*16种颜色,也就是说图片很失去很多彩色信息;RGB_565类型的颜色值同样是16bit,但是它丢弃了透明度信息,可以表示32*64*32种颜色值。

    2 颜色矩阵
    颜色矩阵是一个5*4的矩阵,用来对图片颜色值进行处理。定义颜色矩阵和颜色值如下如下:


    进行如下矩阵运算:

    结果R为4*1的矩阵,这个矩阵就是新的颜色值,R中每个通道的值分别如下:
    R’ = a*R + b*G + c*B + d*A + e;
    G’ = f*R + g*G + h*B + i*A + j;
    B’ = k*R + l*G + m*B + n*A + o;
    A’ = p*R + q*G + r*B + s*A + t;

    这样看起来或许很抽象,很难理解颜色矩阵和结果R直接的关系,我们假设颜色矩阵值如下所示:

    那么结果为:
    R’ = R;
    G’ = G;
    B’ = B;
    A’ = A;
    也就是说,新的颜色值跟原先的一样!再看一个例子,颜色矩阵取值为:

    结果为:
    R’ = R + 100;
    G’ = G + 100;
    B’ = B;
    A’ = A;
    新的颜色值中,红色通道值和绿色通道值分别增加了100,此时图片会泛黄(因为R + G = Yellow)。

    从上面的几个例子我们很容易就能明白颜色矩阵中的每个分量(每一列)的意义:
    第一行决定红色,
    第二行决定绿色,
    第三行决定蓝色,
    第四行决定了透明度,
    第五列是颜色的偏移量。
    至此我们应该能理解如何通过颜色矩阵来改变颜色值的各个分量了。

    下面是用于Android的一段代码,用于将图片处理成泛黄的效果:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    
        public static Bitmap testBitmap(Bitmap bitmap)
        {
            Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
                    bitmap.getHeight(), Config.RGB_565);
     
            Canvas canvas = new Canvas(output);
     
            Paint paint = new Paint();        
            ColorMatrix cm = new ColorMatrix();
            float[] array = {1,0,0,0,100,
                    0,1,0,0,100,
                    0,0,1,0,0,
                    0,0,0,1,0};
            cm.set(array);
            paint.setColorFilter(new ColorMatrixColorFilter(cm));
     
            canvas.drawBitmap(bitmap, 0, 0, paint);
            return output;
        }

    3 坐标变换矩阵
    对图片的操作除了颜色值的处理外,最常用的就是空间坐标的变换了,常见的效果有平移、旋转、拉伸等,这其实也是通过一个矩阵来完成的。坐标变换矩阵是一个3*3的矩阵,通过与一个类似(X,Y,1)的坐标值的矩阵乘法运算,能够将这个坐标值转换成一个新的坐标值,计算过程如下:

    结果为:
    x’=a*x+b*y+c
    y’=d*x+e*y+f
    同颜色矩阵一样,如果坐标变换矩阵如下,则新的坐标值X、Y增加50,也就是说图片的每一点都平移了(50,50)的距离,即图片整体平移到了(50,50)坐标处。

    如果坐标变换矩阵如下,则所有的X、Y坐标都增大两倍,也就是说图片被放大了两倍,其他缩放效果原理类似。

    更复杂一点的还有旋转效果,一个旋转变换矩阵如下:

    结果为x’ = xcosθ – ysinθ 与 y’ = xsinθ + ycosθ,这个结果的效果是绕原点逆时针旋转θ度角。

    下面是用于Android的一段示例代码,用于将图片平移,也就是裁剪的效果,其他效果可以参照对应坐标变换矩阵修改即可:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    
        public static Bitmap test1Bitmap(Bitmap bitmap)
        {
            Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
                    bitmap.getHeight(), Config.RGB_565);
     
            Canvas canvas = new Canvas(output);
     
            Paint paint = new Paint();        
            Matrix cm = new Matrix();
     
            float[] array = {1,0,50,
                    0,1,50,
                    0,0,1};
            cm.setValues(array);
            canvas.drawBitmap(bitmap, cm, paint);
            return output;
        }
     
  • 相关阅读:
    docker微服务部署之:三,搭建Zuul微服务项目
    docker微服务部署之:二、搭建文章微服务项目
    docker微服务部署之:一,搭建Eureka微服务项目
    docker安装Tomcat软件,部署项目
    tomcat运行springboot项目war包
    使用Docker构建jdk1.8镜像
    docker安装MySQL软件
    InvalidKeyException: Illegal key size
    BeanUtils.copyProperties实现po,vo,dto之间的转换
    java集合之HashMap源码解读
  • 原文地址:https://www.cnblogs.com/cywin888/p/3210088.html
Copyright © 2011-2022 走看看