Android--ColorMatrix改变图片颜色

简介:

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 }
复制代码

  效果展示:

 


本文转自承香墨影博客园博客,原文链接:http://www.cnblogs.com/plokmju/p/android_ColorMatrix.html,如需转载请自行联系原作者


相关文章
|
4月前
|
API Android开发 开发者
Android颜色渐变动画效果的实现
本文介绍了在Android中实现颜色渐变动画效果的方法,重点讲解了插值器(TypeEvaluator)的使用与自定义。通过Android自带的颜色插值器ArgbEvaluator,可以轻松实现背景色的渐变动画。文章详细分析了ArgbEvaluator的核心代码,并演示了如何利用Color.colorToHSV和Color.HSVToColor方法自定义颜色插值器MyColorEvaluator。最后提供了完整的源码示例,包括ColorGradient视图类和MyColorEvaluator类,帮助开发者更好地理解和应用颜色渐变动画技术。
138 3
|
4月前
|
Java Android开发
Android背景颜色滑动渐变效果(上下滑动,左右滑动)
本文分享了一种通过ScrollView实现滑动变色效果的简单方法。主要步骤包括:1) 在布局中添加ScrollView并确保内容可滑动;2) 获取屏幕高度;3) 获取控件高度;4) 使用GradientDrawable设置渐变颜色;5) 根据控件与屏幕高度比例动态调整颜色数量。示例代码展示了如何在滑动时根据比例改变背景颜色,实现流畅的视觉效果。
150 0
|
4月前
|
XML Android开发 数据格式
Android利用selector(选择器)实现图片动态点击效果
本文介绍了Android中ImageView的`src`与`background`属性的区别及应用,重点讲解如何通过设置背景选择器实现图片点击动态效果。`src`用于显示原图大小,不拉伸;`background`可随组件尺寸拉伸。通过创建`selector_setting.xml`,结合`setting_press.xml`和`setting_normal.xml`定义按下和正常状态的背景样式,提升用户体验。示例代码展示了具体实现步骤,包括XML配置和形状定义。
202 3
Android利用selector(选择器)实现图片动态点击效果
|
4月前
|
Java Android开发
Android图片的手动放大缩小
本文介绍了通过缩放因子实现图片放大缩小的功能,效果如动图所示。关键步骤包括:1) 在布局文件中设置 `android:scaleType=&quot;matrix&quot;`;2) 实例化控件并用 `ScaleGestureDetector` 处理缩放手势;3) 使用 `Matrix` 对图片进行缩放处理。为避免内存崩溃,可在全局配置添加 `android:largeHeap=&quot;true&quot;`。代码中定义了 `beforeScale` 和 `nowScale` 变量控制缩放范围,确保流畅体验。
153 8
|
4月前
|
缓存 编解码 Android开发
Android内存优化之图片优化
本文主要探讨Android开发中的图片优化问题,包括图片优化的重要性、OOM错误的成因及解决方法、Android支持的图片格式及其特点。同时介绍了图片储存优化的三种方式:尺寸优化、质量压缩和内存重用,并详细讲解了相关的实现方法与属性。此外,还分析了图片加载优化策略,如异步加载、缓存机制、懒加载等,并结合多级缓存流程提升性能。最后对比了几大主流图片加载框架(Universal ImageLoader、Picasso、Glide、Fresco)的特点与适用场景,重点推荐Fresco在处理大图、动图时的优异表现。这些内容为开发者提供了全面的图片优化解决方案。
165 1
|
4月前
|
Android开发 开发者
Android自定义view获取attr中自定义颜色的问题
本文针对Android自定义View在布局中设置颜色时遇到的问题进行分析与解决。问题表现为通过`getAttributeIntValue`方法获取颜色时,使用资源引用(如`@color/colorPrimary`)无法正确获取,而直接使用十六进制颜色值(如`#ff0000`)则正常。经过源码分析,发现是属性格式定义及获取方式不当导致。解决方案为将`attrs`文件中颜色属性的格式改为`reference|color`,并使用`TypedArray`的`getColor`方法获取颜色值,确保资源引用和直接颜色值均能正确解析。希望本文能帮助遇到类似问题的开发者。
|
Java Android开发
android 下载图片的问题
android 下载图片的问题
110 3
|
存储 缓存 编解码
Android经典面试题之图片Bitmap怎么做优化
本文介绍了图片相关的内存优化方法,包括分辨率适配、图片压缩与缓存。文中详细讲解了如何根据不同分辨率放置图片资源,避免图片拉伸变形;并通过示例代码展示了使用`BitmapFactory.Options`进行图片压缩的具体步骤。此外,还介绍了Glide等第三方库如何利用LRU算法实现高效图片缓存。
161 20
Android经典面试题之图片Bitmap怎么做优化
|
Android开发
Android经典实战之Textview文字设置不同颜色、下划线、加粗、超链接等效果
本文介绍了 `SpannableString` 在 Android 开发中的强大功能,包括如何在单个字符串中应用多种样式,如颜色、字体大小、风格等,并提供了详细代码示例,展示如何设置文本颜色、添加点击事件等,助你实现丰富文本效果。
871 4
|
数据处理 开发工具 数据安全/隐私保护
Android平台RTMP推送|轻量级RTSP服务|GB28181接入之文字、png图片水印的精进之路
本文探讨了Android平台上推流模块中添加文字与PNG水印的技术演进。自2015年起,为了满足应急指挥及安防领域的需求,逐步发展出三代水印技术:第一代为静态文字与图像水印;第二代实现了动态更新水印内容的能力,例如实时位置与时间信息;至第三代,则优化了数据传输效率,直接使用Bitmap对象传递水印数据至JNI层,减少了内存拷贝次数。这些迭代不仅提升了用户体验和技术效率,也体现了开发者追求极致与不断创新的精神。
146 7