Android绘图机制与处理技巧(二)——Android图像处理之色彩特效处理

Android对于图片处理,最常使用到的数据结构是位图——Bitmap,它包含了一张图片所有的数据。整个图片都是由点阵和颜色值组成的,所谓点阵就是一个包含像素的矩阵,每一个元素对应着图片的一个像素。而颜色值——ARGB,分别对应透明图、红、绿、蓝这四个通道分量,它们共同决定了每个像素点显示的颜色。

色彩矩阵分析

在色彩处理中,通常使用以下三个角度来描述一个图像。

  • 色调——物体传播的颜色
  • 饱和度——颜色的纯度,从0(灰)到100%(饱和)来进行描述
  • 亮度——颜色的相对明暗程度

而在Android中,系统使用一个颜色矩阵——ColorMatrix,来处理图像的这些色彩效果。Android中颜色矩阵是一个4x5的数字矩阵,它用来对图片的色彩进行处理。而对于每个像素点,都有一个颜色分量矩阵用来保存颜色的RGBA值,如下图所示:

?????afkpbglqchmrdinsejot?????颜色矩阵A

????????RGBA1????????颜色分量矩阵C

图中矩阵A就是一个4x5的颜色矩阵。在Android中,它会以一维数组的形式来存储[a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t],而C则是一个颜色分量矩阵。在处理图像时,使用矩阵乘法运算AC来处理颜色分量矩阵,如下图所示:

?????R1G1B1A1?????矩阵乘法运算D=AC

其中计算过程如下:

R1 = axR + bxG + cxB + dxA + e;

G1 = fxR + gxG + hxB + ixA + j;

B1 = kxR + lxG + mxB + nxA + o;

A1 = pxR + qxG + rxB + sxA + t;

从这个公式可以发现,对于颜色矩阵A是按以下方式划分的。

  • 第一行的abcde值决定新的颜色值中的R——红色
  • 第二行的fghij值决定新的颜色值中的G——绿色
  • 第一行的klmno值决定新的颜色值中的B——蓝色
  • 第一行的pqrst值决定新的颜色值中的A——透明度
  • 矩阵A中的第五列——ejot值分别用来决定每个分量中的offset,即偏移量

现在我们重新看一下矩阵变换的计算公式,以R分量为例。如果令a=1,b、c、d、e都等于0,那么计算结果为R1=R。因此,可以构造出一个矩阵,如下图所示:

?????10000100001000010000?????初始矩阵

如果把这个矩阵带入公式D=AC,那么根据矩阵乘法运算法则,可以得到R1=R。因此这个矩阵通常被用来作为初始的颜色矩阵来使用,它不会对原有颜色值进行任何变化。

当要变换颜色值的时候,通常有两种方法。一种是直接改变颜色的offset,即偏移量的值来修改颜色分量,另一种方法是直接改变对应RGBA值的系数来调整颜色分量的值。

改变偏移量

要修改R1的值,只要将第五列的值进行修改即可。即改变颜色的偏移量,其他值保持初始矩阵的值,如下图所示:

?????100001000010000110010000?????改变颜色偏移量

在上面这个矩阵中,修改了R、G所对应的颜色偏移量,那么最后的处理结果就是图像的红色、绿色分量增加了100。而红色混合绿色会得到黄色,所以最终的颜色处理结果就是让整个图像的色调偏黄色。

改变颜色系数

如果修改颜色分量中的某个系数值,而其他值依然保持初始矩阵的值,如下图所示:

?????10000200001000010000?????改变颜色系数

在上面这个矩阵中,改变了G分量所对应的系数g,这样在矩阵运算后G分量会变为以前的两倍,最终结果就是图像的色调更加偏绿。

改变色光属性

图像的色调、饱和度、亮度这三个属性在图像处理中的使用非常之多。在Android中,系统封装了一个类——ColorMatrix,也就是颜色矩阵。通过这个类,可以很方便地通过改变矩阵值来处理颜色效果。创建一个ColorMatrix对象非常简单,代码如下:

ColorMatrix colorMatrix = new ColorMatrix();

下面处理不同的色光属性。

  • 色调

Android提供了setRotate(int axis, float degrees)来设置颜色的色调。第一个参数,系统分别使用0、1、2来代表Red、Green、Blue三种颜色的处理;而第二个参数,就是需要处理的值,代码如下:

        ColorMatrix hueMatrix = new ColorMatrix();
        hueMatrix.setRotate(0, hue1);
        hueMatrix.setRotate(1, hue2);
        hueMatrix.setRotate(2, hue3);

通过这样的方法,可以为RGB三种颜色分量分别重新设置了不同的色调值。

  • 饱和度

Android系统提供了setSaturation(float sat)方法来设置颜色的饱和度值,代码如下:

        //设置颜色的饱和度
        ColorMatrix saturationMatrix = new ColorMatrix();
        //saturation参数即代表设置颜色的饱和度的值,当饱和度为0时,图像就变成灰度图像了
        saturationMatrix.setSaturation(saturation);
  • 亮度

Android系统提供了setScale(float rScale, float gScale, float bScale, float aScale)方法来设置颜色的亮度值。当三原色以相同的比例进行混合时,就会显示出白色。系统也正是根据这个原理来改变一个图像的亮度的。当亮度为0时,图像就变为全黑了,代码如下所示:

        //设置颜色的亮度
        ColorMatrix lumMatrix = new ColorMatrix();
        lumMatrix.setScale(lum, lum, lum, 1);

除了单独使用上面三种方式进行颜色效果的处理之外,Android系统还封装了矩阵的乘法运算。它提供了postConcat(ColorMatrix postmatrix)方法来将矩阵的作用效果混合,从而叠加处理效果,代码如下所示:

        //将矩阵的作用效果混合,从而叠加处理效果
        ColorMatrix imageMatrix = new ColorMatrix();
        imageMatrix.postConcat(hueMatrix);
        imageMatrix.postConcat(saturationMatrix);
        imageMatrix.postConcat(lumMatrix);

在下面的例子中,通过滑动三个SeekBar来改变不同色光属性的数值,并将这些数值作用到对应的矩阵中。最后通过postConcat()方法来显示混合的处理效果。

滑动SeekBar获取输入值的代码如下所示:

package com.huangfei.example;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.SeekBar;

/**
 * 通过滑动三个SeekBar来改变不同色光属性的数值,并将这些数值作用到对应的矩阵中
 */
public class PrimaryColorActivity extends Activity implements SeekBar.OnSeekBarChangeListener {

    private static final int MAX_VALUE = 255;
    private static final int MID_VALUE = 127;

    private ImageView mImageView;
    private float mHue, mSaturation, mLum;
    private Bitmap mBitmap;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_primary_color);
        mBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.test3);

        mImageView = (ImageView) findViewById(R.id.imageview);
        SeekBar seekBarHue = (SeekBar) findViewById(R.id.seekbarHue);
        SeekBar seekBarSaturation = (SeekBar) findViewById(R.id.seekbarSaturation);
        SeekBar seekBarLum = (SeekBar) findViewById(R.id.seekbarLum);

        seekBarHue.setOnSeekBarChangeListener(this);
        seekBarSaturation.setOnSeekBarChangeListener(this);
        seekBarLum.setOnSeekBarChangeListener(this);

        //设置最大值
        seekBarHue.setMax(MAX_VALUE);
        seekBarSaturation.setMax(MAX_VALUE);
        seekBarLum.setMax(MAX_VALUE);

        //设置进度
        seekBarHue.setProgress(MID_VALUE);
        seekBarSaturation.setProgress(MID_VALUE);
        seekBarLum.setProgress(MID_VALUE);

        mImageView.setImageBitmap(mBitmap);
    }

    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        switch (seekBar.getId()) {
            case R.id.seekbarHue://色调
                mHue = (progress - MID_VALUE) * 1.0f / MID_VALUE * 180;
                break;
            case R.id.seekbarSaturation://饱和度
                mSaturation = progress * 1.0f / MID_VALUE;
                break;
            case R.id.seekbarLum://亮度
                mLum = progress * 1.0f / MID_VALUE;
                break;
        }
        mImageView.setImageBitmap(ImageHelper.handleImageEffect(mBitmap, mHue, mSaturation, mLum));
    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {

    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {

    }
}

设置图像矩阵的代码如下:

    /**
     *改变图像色光属性
     * @param bm
     * @param hue 色调
     * @param saturation 饱和度
     * @param lum 亮度
     * @return
     */
    public static Bitmap handleImageEffect(Bitmap bm, float hue, float saturation, float lum) {
        //设置颜色的色调
        ColorMatrix hueMatrix = new ColorMatrix();
        //第一个参数,系统分别使用0、1、2来代表Red、Green、Blue三种颜色的处理;而第二个参数,就是需要处理的值
        hueMatrix.setRotate(0, hue);
        hueMatrix.setRotate(1, hue);
        hueMatrix.setRotate(2, hue);

        //设置颜色的饱和度
        ColorMatrix saturationMatrix = new ColorMatrix();
        //saturation参数即代表设置颜色的饱和度的值,当饱和度为0时,图像就变成灰度图像了
        saturationMatrix.setSaturation(saturation);

        //设置颜色的亮度
        ColorMatrix lumMatrix = new ColorMatrix();
        lumMatrix.setScale(lum, lum, lum, 1);

        //将矩阵的作用效果混合,从而叠加处理效果
        ColorMatrix imageMatrix = new ColorMatrix();
        imageMatrix.postConcat(hueMatrix);
        imageMatrix.postConcat(saturationMatrix);
        imageMatrix.postConcat(lumMatrix);

        /**
         * 设置好处理的颜色矩阵后,通过使用Paint类的setColorFilter()方法,将通过imageMatrix构造的
         * ColorMatrixColorFilter对象传递进去,并使用这个画笔来绘制原来的图像,从而将颜色矩阵作用到原图中
         */
        Paint paint = new Paint();
        paint.setColorFilter(new ColorMatrixColorFilter(imageMatrix));
        /**
         * Android系统也不允许直接修改原图,类似Photoshop中的锁定,必须通过原图创建一个同样大小的Bitmap,并将
         * 原图绘制到该Bitmap中,以一个副本的形式来修改图像。
         */
        Bitmap bitmap = Bitmap.createBitmap(bm.getWidth(), bm.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        canvas.drawBitmap(bm, 0, 0 ,paint);
        return bitmap;
    }

效果图如下:

Android颜色矩阵——ColorMatrix

通过调整颜色矩阵可以改变一副图像的色彩效果,图像处理很大程度上就是在寻找处理图像的颜色矩阵。不仅仅可以通过Android系统提供的API来进行ColorMatrix的修改,同样可以精确地修改矩阵的值来实现颜色效果的改变。下面模拟一个4x5的颜色矩阵,通过修改矩阵中的值,来观察图片的效果,程序运行后的效果如下图:

通过GridLayout来进行布局,动态添加20个EditText来创建4x5的矩阵,GridLayout布局代码如下:

    <GridLayout
        android:id="@+id/group"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="3"
        android:columnCount="5"
        android:rowCount="4" />

动态创建EditText,添加到GridLayout并初始化矩阵的代码如下所示:

package com.huangfei.example;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.GridLayout;
import android.widget.ImageView;

/**
 * Created by Administrator on 2016/5/26.
 * 模拟一个4x5的颜色矩阵
 */
public class ColorMatrixActivity extends Activity {
    private ImageView mImageView;
    private GridLayout mGroup;
    private Bitmap bitmap;
    private int mEtWidth, mEtHeight;
    private EditText[] mEts = new EditText[20];
    private float[] mColorMatrix = new float[20];

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_color_matrix);
        bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.test1);
        mImageView = (ImageView) findViewById(R.id.imageview);
        mGroup = (GridLayout) findViewById(R.id.group);
        mImageView.setImageBitmap(bitmap);

        mGroup.post(new Runnable() {
            @Override
            public void run() {
                // 获取宽高信息
                mEtWidth = mGroup.getWidth() / 5;
                mEtHeight = mGroup.getHeight() / 4;
                addEts();
                initMatrix();
            }
        });
    }

    // 初始化颜色矩阵为初始状态
    private void initMatrix() {
        for (int i = 0; i < 20; i++) {
            if (i % 6 == 0)
                mEts[i].setText(String.valueOf(1));
            else
                mEts[i].setText(String.valueOf(0));
        }
    }

    // 添加EditText
    private void addEts() {
        for (int i = 0; i < 20; i++) {
            mEts[i] = new EditText(this);
            mGroup.addView(mEts[i], mEtWidth, mEtHeight);
        }
    }

    // 获取矩阵值
    private void getMatrix() {
        for (int i = 0; i < 20; i++) {
            mColorMatrix[i] = Float.valueOf(mEts[i].getText().toString());
        }
    }

    // 将矩阵值设置到图像
    private void setImageMatrix() {
        Bitmap bmp = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
        ColorMatrix colorMatrix = new ColorMatrix();
        colorMatrix.set(mColorMatrix);
        Canvas canvas = new Canvas(bmp);
        Paint paint = new Paint();
        paint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
        canvas.drawBitmap(bitmap, 0, 0, paint);
        mImageView.setImageBitmap(bmp);
    }

    // 作用矩阵效果
    public void btnChange(View view) {
        getMatrix();
        setImageMatrix();
    }

    // 重置矩阵效果
    public void btnReset(View view) {
        initMatrix();
        getMatrix();
        setImageMatrix();
    }
}

常用图像颜色矩阵处理效果

灰度效果

颜色矩阵如下所示:

?????0.330.330.3300.590.590.5900.110.110.11000010000?????灰度效果

处理效果如下所示:

图像反转

颜色矩阵如下所示:

??????10000?10000?1011111110?????图像反转

处理效果如下所示:

怀旧效果

颜色矩阵如下所示:

?????0.3930.3490.27200.7690.6860.53400.1890.1680.131000010000?????怀旧效果

处理效果如下所示:

去色效果

颜色矩阵如下所示:

?????1.51.51.501.51.51.501.51.51.500001?1?1?10?????去色效果

处理效果如下所示:

高饱和度

颜色矩阵如下所示:

?????1.438?0.062?0.0620?0.1221.378?0.1220?0.016?0.0161.48300001?0.03?0.05?0.020?????高饱和度

处理效果如下所示:

像素点分析

可以通过改变每个像素点的具体ARGB值,来达到处理一张图像效果的目的。但要注意的是,传递进来的原始图片是不能修改的,一般根据原始图片生成一张新的图片来修改。

在Android中,系统提供了Bitmap.getPixels()方法来帮我们提取整个Bitmap中的像素点,并保存到一个数组中,该方法如下所示:

getPixels(int[] pixels, int offset, int stride, int x, int y, int width, int height)

参数含义如下:

  • pixels——接收位图颜色值的数组
  • offset——写入到pixels[]中的第一个像素索引值
  • stride——用来表示pixels[]数组中每行的像素个数,用于行与行之间区分,绝对值必须大于参数width,但不必大于所要读取图片的宽度w(在width < w 时成立).(stride负数有何作用不知,存疑).另,pixels.length >= stride * height,否则会抛出ArrayIndexOutOfBoundsException异常。 stride > width时,可以在pixels[]数组中添加每行的附加信息,可做它用.
  • x——从位图中读取的第一个像素的x坐标值
  • y——从位图中读取的第一个像素的y坐标值
  • width——从每一行中读取的像素宽度
  • height——读取的行数

通常情况下,可以使用如下代码:

        int width = bm.getWidth();
        int height = bm.getHeight();
        int[] oldPx = new int[width * height];
        bm.getPixels(oldPx, 0, width, 0, 0, width, height);

接下来,就可以获取到每个像素具体的ARGB值了,代码如下所示:

            color = oldPx[i];
            r = Color.red(color);
            g = Color.green(color);
            b = Color.blue(color);
            a = Color.alpha(color);

当获取到具体的颜色值之后,就可以通过相应的算法来修改它的ARGB值,从而来重构一张新的图像,例如进行如下处理:

            r1 = (int) (0.393 * r + 0.769 * g + 0.189 * b);
            g1 = (int) (0.349 * r + 0.686 * g + 0.168 * b);
            b1 = (int) (0.272 * r + 0.534 * g + 0.131 * b);

再通过如下所示代码将新的RGBA值合成像素点:

newPx[i] = Color.argb(a, r1, g1, b1);

最后将处理之后的像素点数组重新set给Bitmap。从而达到图像处理的目的:

bmp.setPixels(newPx, 0, width, 0, 0, width, height);

常用图像像素点处理效果

底片效果

若存在ABC3个像素点,要求B点对应的底片效果算法,代码如下:

B.r = 255 - B.r;

B.g = 255 - B.g;

B.b = 255 - B.b;

实现代码如下:

    //底片效果
    public static Bitmap handleImageNegative(Bitmap bitmap) {
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        int color;
        int r, g, b, a;

        Bitmap btm = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);

        int[] oldPx = new int[width * height];
        int[] newPx = new int[width * height];
        bitmap.getPixels(oldPx, 0, width, 0, 0, width, height);

        for (int i = 0; i < width * height; i++) {
            color = oldPx[i];
            r = Color.red(color);
            g = Color.green(color);
            b = Color.blue(color);
            a = Color.alpha(color);

            r = 255 - r;
            g = 255 - g;
            b = 255 - 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;
            newPx[i] = Color.argb(a, r, g, b);
        }
        btm.setPixels(newPx, 0, width, 0, 0, width, height);
        return btm;
    }

老照片效果

求某像素点的老照片效果算法,代码如下:

for (int i = 0; i < width * height; i++) {
            color = oldPx[i];
            a = Color.alpha(color);
            r = Color.red(color);
            g = Color.green(color);
            b = Color.blue(color);

            r1 = (int) (0.393 * r + 0.769 * g + 0.189 * b);
            g1 = (int) (0.349 * r + 0.686 * g + 0.168 * b);
            b1 = (int) (0.272 * r + 0.534 * g + 0.131 * b);

            if (r1 > 255) {
                r1 = 255;
            }
            if (g1 > 255) {
                g1 = 255;
            }
            if (b1 > 255) {
                b1 = 255;
            }

            newPx[i] = Color.argb(a, r1, g1, b1);
        }

浮雕效果

求某像素点的浮雕效果算法,代码如下:

        for (int i = 1; i < width * height; i++) {
            colorBefore = oldPx[i - 1];
            a = Color.alpha(colorBefore);
            r = Color.red(colorBefore);
            g = Color.green(colorBefore);
            b = Color.blue(colorBefore);

            color = oldPx[i];
            r1 = Color.red(color);
            g1 = Color.green(color);
            b1 = Color.blue(color);

            r = r - r1 + 127;
            g = g - g1 + 127;
            b = b - b1 + 127;
            if (r > 255) {
                r = 255;
            }
            if (g > 255) {
                g = 255;
            }
            if (b > 255) {
                b = 255;
            }
            newPx[i] = Color.argb(a, r, g, b);
        }

效果如下所示:

代码地址

时间: 2024-08-09 02:20:45

Android绘图机制与处理技巧(二)——Android图像处理之色彩特效处理的相关文章

Android群英传知识点回顾——第六章:Android绘图机制与处理技巧

6.1 屏幕的尺寸信息 6.1.1 屏幕参数 6.1.2 系统屏幕密度 6.1.3 独立像素密度dp 6.1.4 单位转换 6.2 2D绘图基础 6.3 Android XML绘图 6.3.1 Bitmap 6.3.2 Shape 6.3.3 Layer 6.3.4 Selector 6.4 Android绘图技巧 6.4.1 Canvas 6.4.2 Layer图层 6.5 Android图像处理之色彩特效处理 6.5.1 色彩矩阵分析 6.5.2 Android颜色矩阵--ColorMatr

第三章 Android绘图机制与处理技巧

1.屏幕尺寸信息 屏幕大小:屏幕对角线长度,单位“寸”:分辨率:手机屏幕像素点个数,例如720x1280分辨率:PPI(Pixels Per Inch):即DPI(Dots Per Inch),它是对角线的像素点数除以屏幕大小得到的:系统屏幕密度:android系统定义了几个标准的DPI值作为手机的固定DPI.(注,最后一个有笔误,正确的是1080x1920)独立像素密度(DP):android系统使用mdpi屏幕作为标准,在这个屏幕上1dp=1px,其他屏幕可以通过比例进行换算.在hdpi中,

Android绘图机制与处理技巧

一屏幕的尺寸信息 1屏幕参数 2系统屏幕密度 3独立像素密度dp 4单位换算 二2D绘图基础 三Android XML 绘图 Bitmap Shape Layer Selector 四绘图技巧 Canvas 一.屏幕的尺寸信息 1屏幕参数 屏幕大小 指屏幕对角线的长度,通常使用"寸"来度量,例如4.7寸手机 5.5寸手机等. 分辨率 分辨率是指手机屏幕的像素点个数,例如720*1280是指屏幕分变率,指宽有720个像素点,高有1280个像素点. PPI 每英寸像素(Pixels Per

Android绘图机制与处理技巧(四)——Android图像处理之画笔特效处理

除了常用的画笔属性,比如普通的画笔(Paint),带边框.填充的style,颜色(Color),宽度(StrokeWidth),抗锯齿(ANTI_ALIAS_FLAG)等,Android还提供了各种各样专业的画笔工具,如记号笔.毛笔.蜡笔等,使用它们可以实现更加丰富的效果. PorterDuffXfermode 下图中列举了16种PorterDuffXfermode,有点像数学中集合的交集.并集这样的概念,它控制的是两个图像间的混合显示模式. PorterDuffXfermode设置的是两个图层

Android绘图机制(一) View类

对android绘图机制的理解,在Android学习中可谓至关重要,包括自定义控件也是使用非常频繁的内容.最近在项目中遇到一个比较棘手的问题,项目中好几个模块都用到ListView或者GridView的”下拉刷新,上拉加载更多“功能 .一开始在网上找了大牛写的作品,用在项目中后发现时不时会出现卡壳的现象,改进以后会有所改善,不过还是感觉有所欠缺.无奈我是个处女座菜鸟,尝试着找出这些问题的根本原因却发现无从下手,所以先补补基础.( 纯文字看着确实很费劲,所以顺便引用下其他的文章)  概述 View

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

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

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

Android中图像的色彩特效处理: Android中色彩特效处理的基础: Android中对于图片的处理通常使用的是Bitmap(位图),Bitmap中包含了一张图片的所有信息(点阵和颜色值).点阵是一个包含像素的矩阵,每一个元素对应着图片的一个像素,而每一个像素都由一个颜色矩阵分量来保存该像素点的ARGB信息.颜色值--ARGB分别对应透明度,红色,绿色,蓝色,共同决定了像素点显示的颜色. 在Android中系统使用一个4x5的颜色矩阵(ColorMatrix)来处理图片的色彩效果(以一维数

Android群英传知识点回顾——第七章:Android动画机制与使用技巧

7.1 Android View动画框架 7.1.1 透明度动画 7.1.2 旋转动画 7.1.3 位移动画 7.1.4 缩放动画 7.1.5 动画集合 7.2 Android属性动画分析 7.2.1 ObjectAnimator 7.2.2 PropertyValuesHolder 7.2.3 ValueAnimator 7.2.4 动画事件的监听 7.2.5 AnimatorSet 7.2.6 在XML中使用属性动画 7.2.7 View的animate方法 7.3 Android布局动画

Android动画机制与使用技巧(五)——Android 5.X SVG 矢量动画机制

Google在Android 5.X 中增加了对SVG 矢量图形的支持,这对于创建新的高效率动画具有非常重大的意义.那首先了解SVG的含义. 可伸缩矢量图形(Scalable Vector Graphics) 定义用于网络的基于矢量的图形 使用XML格式定义图形 图像在放大或改变尺寸的情况下其图形质量不会有所损失 万维网联盟的标准 与诸如DOM和XSL之类的W3C标准是一个整体 SVG在Web上的应用非常广泛,在Android 5.X之前的Android版本上,可以通过一些第三方开源库来在And