zoukankan      html  css  js  c++  java
  • Android--ColorMatrix改变图片颜色

    前言

      本篇博客讲解如何通过改变图片像素点RGB的值的方式,在Android中改变图片的颜色。在最后将以一个简单的Demo来作为演示。

       本篇博客的主要内容:

    1. ColorMatrix
    2. 使用ColorMatrix改变图片颜色的步骤
    3. 改变图片RGBA值的Demo

    ColorMatrix

      在Android中,图片是以一个个RGBA的像素点的形式加载到内存中的,所以如果需要改变图片的颜色,就需要针对这一个个像素点的RGBA的值进行修改,其实主要是RGB,A是透明度。在Android下,修改图片RGBA的值需要ColorMatrix类的支持,它定义了一个5*4的float[]类型的矩阵,矩阵中每一行表示RGBA中的一个参数。

      一般常用指定ColorMatrix的RGBA值的方式有两种:

    • 通过构造函数ColorMatrix(float[] src)直接得到i一个ColorMatrix对象,其中src参数为5*4的float[]类型的矩阵。
    • 通过构造函数ColorMatrix()得到ColorMatrix对象,再通过set(float[] src)指定一个5*4的float[]类型的矩阵。

      下面是定义了一个不修改的原图的RGBA的ColorMatrix。

    1         ColorMatrix colorMatrix = new ColorMatrix();
    2         colorMatrix.set(new float[] { 
    3                 1, 0, 0, 0, 0, 
    4                 0, 1, 0, 0, 0, 
    5                 0, 0, 1,0, 0, 
    6                 0, 0, 0, 1, 0 
    7                 });

      可以看到,代码中,第三行定义的是R,第四行定义的是G,第五行定义的是B,第六行定义的是A。在定义的时候,需要注意数组的顺序必须正确。

      这个矩阵定义的是一连串float数组,其中不同的位置代表了不同的RGBA值,它的范围在0.0f~2.0f之间,1为保持原图的RGBA值。

    使用ColorMatrix改变图片颜色的步骤

      上面介绍了ColorMatrix设置图片的颜色,但是仅仅使用它还无法完成图片颜色的修改,需要配合Canvas和Paint使用,具体步骤如下:

    1. 通过Bitmap.createBitmap()方法获得一个空白的Bitmap对象。
    2. 定义Paint独享,通过Paint.setColorFilter(ColorFilter)方法设置Paint的RGBA值。
    3. 使用Canvas.drawBitmap()方法把原图使用定义的Paint画到空白的Bitmap对象上即可获得改变RGBA值后的图像。

      需要说明一下的是Paint.setColorFilter()方法传递的是一个ColorFilter对象,可以使用它的子类ColorMatrixColorFilter包装我们定义好的ColorMatrix。

    改变图片RGBA值的Demo

      上面已经简单讲解了如何使用ColorMatrix定义一个RGBA值的矩阵,然后介绍了使用ColorMatrix的步骤,下面通过一个简单的Demo来演示如何使用它。在Demo中定义了四个SeekBar,分别代表RGBA,拖动其中的某个SeekBar,改变位图原本的颜色。注释都比较全,这里就不再赘述了。

      布局代码:

     1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     2     xmlns:tools="http://schemas.android.com/tools"
     3     android:layout_width="match_parent"
     4     android:layout_height="match_parent"
     5     android:orientation="vertical"
     6     android:paddingBottom="@dimen/activity_vertical_margin"
     7     android:paddingLeft="@dimen/activity_horizontal_margin"
     8     android:paddingRight="@dimen/activity_horizontal_margin"
     9     android:paddingTop="@dimen/activity_vertical_margin"
    10     tools:context=".MainActivity" >
    11 
    12     <TextView
    13         android:layout_width="wrap_content"
    14         android:layout_height="wrap_content"
    15         android:text="R" />
    16 
    17     <SeekBar
    18         android:id="@+id/sb_red"
    19         android:layout_width="match_parent"
    20         android:layout_height="wrap_content"
    21         android:max="255"
    22         android:progress="128" />
    23 
    24     <TextView
    25         android:layout_width="wrap_content"
    26         android:layout_height="wrap_content"
    27         android:text="G" />
    28 
    29     <SeekBar
    30         android:id="@+id/sb_green"
    31         android:layout_width="match_parent"
    32         android:layout_height="wrap_content"
    33         android:max="255"
    34         android:progress="128" />
    35 
    36     <TextView
    37         android:layout_width="wrap_content"
    38         android:layout_height="wrap_content"
    39         android:text="B" />
    40 
    41     <SeekBar
    42         android:id="@+id/sb_blue"
    43         android:layout_width="match_parent"
    44         android:layout_height="wrap_content"
    45         android:max="255"
    46         android:progress="128" />
    47 
    48     <TextView
    49         android:layout_width="wrap_content"
    50         android:layout_height="wrap_content"
    51         android:text="A" />
    52 
    53     <SeekBar
    54         android:id="@+id/sb_alpha"
    55         android:layout_width="match_parent"
    56         android:layout_height="wrap_content"
    57         android:max="255"
    58         android:progress="128" />
    59 
    60     <ImageView
    61         android:id="@+id/iv_show"
    62         android:layout_width="wrap_content"
    63         android:layout_height="wrap_content"
    64         android:src="@drawable/painter" />
    65 
    66 </LinearLayout>

      实现代码:

     1 package cn.bgxt.colormatrixdemo;
     2 
     3 import android.os.Bundle;
     4 import android.util.Log;
     5 import android.widget.ImageView;
     6 import android.widget.SeekBar;
     7 import android.widget.SeekBar.OnSeekBarChangeListener;
     8 import android.app.Activity;
     9 import android.graphics.Bitmap;
    10 import android.graphics.BitmapFactory;
    11 import android.graphics.Canvas;
    12 import android.graphics.ColorMatrix;
    13 import android.graphics.ColorMatrixColorFilter;
    14 import android.graphics.Matrix;
    15 import android.graphics.Paint;
    16 
    17 public class MainActivity extends Activity {
    18     private SeekBar sb_red, sb_green, sb_blue,sb_alpha;
    19     private ImageView iv_show;
    20     private Bitmap afterBitmap;
    21     private Paint paint;
    22     private Canvas canvas;
    23     private Bitmap baseBitmap;
    24 
    25     @Override
    26     protected void onCreate(Bundle savedInstanceState) {
    27         super.onCreate(savedInstanceState);
    28         setContentView(R.layout.activity_main);
    29 
    30         iv_show = (ImageView) findViewById(R.id.iv_show);
    31         sb_red = (SeekBar) findViewById(R.id.sb_red);
    32         sb_green = (SeekBar) findViewById(R.id.sb_green);
    33         sb_blue = (SeekBar) findViewById(R.id.sb_blue);
    34         sb_alpha = (SeekBar) findViewById(R.id.sb_alpha);
    35         
    36         sb_red.setOnSeekBarChangeListener(seekBarChange);
    37         sb_green.setOnSeekBarChangeListener(seekBarChange);
    38         sb_blue.setOnSeekBarChangeListener(seekBarChange);
    39         sb_alpha.setOnSeekBarChangeListener(seekBarChange);
    40 
    41         // 从资源文件中获取图片
    42         baseBitmap = BitmapFactory.decodeResource(getResources(),
    43                 R.drawable.painter);
    44         // 获取一个与baseBitmap大小一致的可编辑的空图片
    45         afterBitmap = Bitmap.createBitmap(baseBitmap.getWidth(),
    46                 baseBitmap.getHeight(), baseBitmap.getConfig());
    47         canvas = new Canvas(afterBitmap);
    48         paint = new Paint();
    49     }
    50 
    51     private SeekBar.OnSeekBarChangeListener seekBarChange = new OnSeekBarChangeListener() {
    52 
    53         @Override
    54         public void onStopTrackingTouch(SeekBar seekBar) {
    55             // 获取每个SeekBar当前的值
    56             float progressR = sb_red.getProgress()/128f;
    57             float progressG = sb_green.getProgress()/128f;
    58             float progressB = sb_blue.getProgress()/128f;
    59             float progressA=sb_alpha.getProgress()/128f;
    60             Log.i("main", "R:G:B="+progressR+":"+progressG+":"+progressB);
    61             // 根据SeekBar定义RGBA的矩阵
    62             float[] src = new float[]{
    63                     progressR, 0, 0, 0, 0, 
    64                     0, progressG, 0, 0, 0,
    65                     0, 0, progressB, 0, 0, 
    66                     0, 0, 0, progressA, 0};
    67             // 定义ColorMatrix,并指定RGBA矩阵
    68             ColorMatrix colorMatrix = new ColorMatrix();
    69             colorMatrix.set(src);
    70             // 设置Paint的颜色
    71             paint.setColorFilter(new ColorMatrixColorFilter(src));
    72             // 通过指定了RGBA矩阵的Paint把原图画到空白图片上
    73             canvas.drawBitmap(baseBitmap, new Matrix(), paint);
    74             iv_show.setImageBitmap(afterBitmap);
    75         }
    76 
    77         @Override
    78         public void onStartTrackingTouch(SeekBar seekBar) {
    79         }
    80 
    81         @Override
    82         public void onProgressChanged(SeekBar seekBar, int progress,
    83                 boolean fromUser) {
    84         }
    85     };
    86 }

      效果展示:

      源码下载

     

  • 相关阅读:
    Linux下mysql使用systemctl restart mysqld命令失败
    Linux环境下mysql报错:bash: mysql: command not found 的解决方法
    Linux查看mysql是否启动的命令
    启动MySQL5.7时报错:initialize specified but the data directory has files in it. Aborting.
    ARM64架构下面安装mysql5.7.22
    Python3.6打开EAIDK-610开发板(计算机通用)摄像头拍照并保存
    Python的几种主动结束程序方式
    aarch64架构下安装tensorflow详细过程
    python代码在linux终端中执行报错:Unable to init server: Could not connect: Connection refused
    red hat 报错:apt-get:找不到命令
  • 原文地址:https://www.cnblogs.com/plokmju/p/android_ColorMatrix.html
Copyright © 2011-2022 走看看