对图像进行颜色方面的处理,通过使用颜色矩阵(ColorMatrix)来实现。从而可以达到很多特效如黑白老照片、泛黄旧照片等等。

1.颜色矩阵(ColorMatrix)

这里有详细的介绍:http://developer.Android.com/reference/android/graphics/ColorMatrix.html

不过是英文的,在这里我就先导读一下。

一张位图可以转换为一个5*4的矩阵,涉及到颜色和透明度。如图1所示。在Android中,颜色矩阵M是以一维数组m=[a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t]的方式进行存储的。

图1

在一张图片中,图像的RGBA(红色、绿色、蓝色、透明度)值决定了该图片所呈现出来的颜色效果。
而图像的RGBA值则存储在一个5*1的颜色分量矩阵C中,由颜色分量矩阵C可以控制图像的颜色效果。颜色分量矩阵C如图2所示。

图2

要想改变一张图片的颜色效果,只需要改变图像的颜色分量矩阵即可。通过颜色矩阵可以很方便的修改图像的颜色分量矩阵。假设修改后的图像颜色分量矩阵为C1,则有如图3所示的颜色分量矩阵计算公式。

图3

由此可见,通过颜色矩阵修改了原图像的RGBA值,从而达到了改变图片颜色效果的目的。并且,通过如图3所示的运算可知,颜色矩阵M的第一行参数abcde决定了图像的红色成分,第二行参数fghij决定了图像的绿色成分,第三行参数klmno决定了图像的蓝色成分,第四行参数pqrst决定了图像的透明度,第五列参数ejot是颜色的偏移量。
通常,改变颜色分量时可以通过修改第5列的颜色偏移量来实现,如图4所示的颜色矩阵M1,通过计算后可以得知该颜色矩阵的作用是使图像的红色分量和绿色分量均增加100,这样的效果就是图片泛黄(因为红色与绿色混合后得到黄色)。

图4

除此之外,也可以通过直接对颜色值乘以某一系数而达到改变颜色分量的目的。如图5所示的颜色矩阵M2,将绿色分量放大了2倍,这样的效果就是图片泛绿色。

图5

实例:

步骤一:我们首先自定义一个view,用来显示我们处理的图片。

ColorView.Java

  1. package com.mycolor;
  2. import android.content.Context;
  3. import android.graphics.Bitmap;
  4. import android.graphics.BitmapFactory;
  5. import android.graphics.Canvas;
  6. import android.graphics.ColorMatrix;
  7. import android.graphics.ColorMatrixColorFilter;
  8. import android.graphics.Paint;
  9. import android.util.AttributeSet;
  10. import android.widget.ImageView;
  11. public class ColorView extends ImageView {
  12. private Paint myPaint = null;
  13. private Bitmap bitmap = null;
  14. private ColorMatrix myColorMatrix = null;
  15. private float[] colorArray = {1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0};
  16. public ColorView(Context context, AttributeSet attrs)
  17. {
  18. super(context, attrs);
  19. bitmap = BitmapFactory.decodeResource(context.getResources(),R.drawable.a2);
  20. invalidate();
  21. }
  22. @Override
  23. protected void onDraw(Canvas canvas) {
  24. super.onDraw(canvas);
  25. //新建画笔对象
  26. myPaint = new Paint();
  27. //描画(原始图片)
  28. canvas.drawBitmap(bitmap,0, 0, myPaint);
  29. //新建颜色矩阵对象
  30. myColorMatrix = new ColorMatrix();
  31. //设置颜色矩阵的值
  32. myColorMatrix.set(colorArray);
  33. //设置画笔颜色过滤器
  34. myPaint.setColorFilter(new ColorMatrixColorFilter(myColorMatrix));
  35. //描画(处理后的图片)
  36. canvas.drawBitmap(bitmap,0,0,myPaint);
  37. invalidate();
  38. }
  39. //设置颜色数值
  40. public void setColorArray(float[] colorArray){
  41. this.colorArray = colorArray;
  42. }
  43. //设置图片
  44. public void setBitmap(Bitmap bitmap){
  45. this.bitmap = bitmap;
  46. }
  47. }

步骤二:自定义我们的布局

main.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:id="@+id/colorView_layout"
  4. android:layout_width="fill_parent"
  5. android:layout_height="fill_parent"
  6. android:orientation="vertical" >
  7. <com.mycolor.ColorView
  8. android:id="@+id/myColorView"
  9. android:layout_width="480dp"
  10. android:layout_height="180dp"/>
  11. <LinearLayout
  12. android:id="@+id/colorlayout1"
  13. android:layout_width="fill_parent"
  14. android:layout_height="wrap_content"
  15. android:orientation="horizontal" >
  16. <EditText
  17. android:id="@+id/Edit1"
  18. android:layout_width="50dp"
  19. android:layout_height="40dp"
  20. android:layout_weight="1"
  21. android:text="1" />
  22. <EditText
  23. android:id="@+id/Edit2"
  24. android:layout_width="50dp"
  25. android:layout_height="40dp"
  26. android:layout_weight="1"
  27. android:text="0"
  28. />
  29. <EditText
  30. android:id="@+id/Edit3"
  31. android:layout_width="50dp"
  32. android:layout_height="40dp"
  33. android:layout_weight="1"
  34. android:text="0" />
  35. <EditText
  36. android:id="@+id/Edit4"
  37. android:layout_width="50dp"
  38. android:layout_height="40dp"
  39. android:layout_weight="1"
  40. android:text="0" />
  41. <EditText
  42. android:id="@+id/Edit5"
  43. android:layout_width="50dp"
  44. android:layout_height="40dp"
  45. android:layout_weight="1"
  46. android:text="0" />
  47. </LinearLayout>
  48. <LinearLayout
  49. android:id="@+id/colorlayout2"
  50. android:layout_width="fill_parent"
  51. android:layout_height="wrap_content"
  52. android:orientation="horizontal" >
  53. <EditText
  54. android:id="@+id/Edit6"
  55. android:layout_width="50dp"
  56. android:layout_height="40dp"
  57. android:layout_weight="1"
  58. android:text="0" />
  59. <EditText
  60. android:id="@+id/Edit7"
  61. android:layout_width="50dp"
  62. android:layout_height="40dp"
  63. android:layout_weight="1"
  64. android:text="1" />
  65. <EditText
  66. android:id="@+id/Edit8"
  67. android:layout_width="50dp"
  68. android:layout_height="40dp"
  69. android:layout_weight="1"
  70. android:text="0" />
  71. <EditText
  72. android:id="@+id/Edit9"
  73. android:layout_width="50dp"
  74. android:layout_height="40dp"
  75. android:layout_weight="1"
  76. android:text="0" />
  77. <EditText
  78. android:id="@+id/Edit10"
  79. android:layout_width="50dp"
  80. android:layout_height="40dp"
  81. android:layout_weight="1"
  82. android:text="0" />
  83. </LinearLayout>
  84. <LinearLayout
  85. android:id="@+id/colorlayout3"
  86. android:layout_width="fill_parent"
  87. android:layout_height="wrap_content"
  88. android:orientation="horizontal" >
  89. <EditText
  90. android:id="@+id/Edit11"
  91. android:layout_width="50dp"
  92. android:layout_height="40dp"
  93. android:layout_weight="1"
  94. android:text="0" />
  95. <EditText
  96. android:id="@+id/Edit12"
  97. android:layout_width="50dp"
  98. android:layout_height="40dp"
  99. android:layout_weight="1"
  100. android:text="0" />
  101. <EditText
  102. android:id="@+id/Edit13"
  103. android:layout_width="50dp"
  104. android:layout_height="40dp"
  105. android:layout_weight="1"
  106. android:text="1" />
  107. <EditText
  108. android:id="@+id/Edit14"
  109. android:layout_width="50dp"
  110. android:layout_height="40dp"
  111. android:layout_weight="1"
  112. android:text="0" />
  113. <EditText
  114. android:id="@+id/Edit15"
  115. android:layout_width="50dp"
  116. android:layout_height="40dp"
  117. android:layout_weight="1"
  118. android:text="0" />
  119. </LinearLayout>
  120. <LinearLayout
  121. android:id="@+id/colorlayout4"
  122. android:layout_width="fill_parent"
  123. android:layout_height="wrap_content"
  124. android:orientation="horizontal" >
  125. <EditText
  126. android:id="@+id/Edit16"
  127. android:layout_width="50dp"
  128. android:layout_height="40dp"
  129. android:layout_weight="1"
  130. android:text="0" />
  131. <EditText
  132. android:id="@+id/Edit17"
  133. android:layout_width="50dp"
  134. android:layout_height="40dp"
  135. android:layout_weight="1"
  136. android:text="0" />
  137. <EditText
  138. android:id="@+id/Edit18"
  139. android:layout_width="50dp"
  140. android:layout_height="40dp"
  141. android:layout_weight="1"
  142. android:text="0" />
  143. <EditText
  144. android:id="@+id/Edit19"
  145. android:layout_width="50dp"
  146. android:layout_height="40dp"
  147. android:layout_weight="1"
  148. android:text="1" />
  149. <EditText
  150. android:id="@+id/Edit20"
  151. android:layout_width="50dp"
  152. android:layout_height="40dp"
  153. android:layout_weight="1"
  154. android:text="0" />
  155. </LinearLayout>
  156. <Button
  157. android:id="@+id/Button"
  158. android:layout_width="fill_parent"
  159. android:layout_height="wrap_content"
  160. android:layout_marginBottom="0dp"
  161. android:text="提交" />
  162. </LinearLayout>

步骤三:完成我们的Activity

  1. package com.mycolor;
  2. import android.app.Activity;
  3. import android.os.Bundle;
  4. import android.view.View;
  5. import android.view.View.OnClickListener;
  6. import android.widget.Button;
  7. import android.widget.EditText;
  8. public class ColorActivity extends Activity  implements OnClickListener{
  9. private Button button = null;
  10. private ColorView colorView = null;
  11. private EditText[] editTextArray = null;
  12. private float colorArray[] = null;
  13. private int[] EditTextID = {R.id.Edit1,R.id.Edit2,R.id.Edit3,R.id.Edit4,R.id.Edit5,
  14. R.id.Edit6,R.id.Edit7,R.id.Edit8,R.id.Edit9,R.id.Edit10,
  15. R.id.Edit11,R.id.Edit12,R.id.Edit13,R.id.Edit14,R.id.Edit15,
  16. R.id.Edit16,R.id.Edit17,R.id.Edit18,R.id.Edit19,R.id.Edit20};
  17. @Override
  18. public void onCreate(Bundle savedInstanceState) {
  19. super.onCreate(savedInstanceState);
  20. setContentView(R.layout.main);
  21. button = (Button)findViewById(R.id.Button);
  22. button.setOnClickListener(this);
  23. editTextArray = new EditText[20];
  24. colorArray = new float[20];
  25. for(int i = 0;i < 20;i++){
  26. editTextArray[i] = (EditText)findViewById(EditTextID[i]);
  27. }
  28. colorView = (ColorView)findViewById(R.id.myColorView);
  29. }
  30. @Override
  31. public void onClick(View v) {
  32. for(int i = 0;i < 20;i++){
  33. colorArray[i] = Float.valueOf(editTextArray[i].getText().toString().trim());
  34. System.out.println("i = " + i + ":" + editTextArray[i].getText().toString().trim());
  35. }
  36. colorView.setColorArray(colorArray);
  37. }
  38. }

这样就可以了。

效果图:

改变值可以呈现不同的效果:

原文参考:点击打开链接

代码:点击下载

Android学习笔记之图像颜色处理(ColorMatrix)的更多相关文章

  1. Android学习笔记-ImageView(图像视图)

    本节引言: 本节介绍的UI基础控件是:ImageView(图像视图),见名知意,就是用来显示图像的一个View或者说控件! 官方API:ImageView;本节讲解的内容如下: ImageView的s ...

  2. 【转】Pro Android学习笔记(三):了解Android资源(上)

    在Android开发中,资源包括文件或者值,它们和执行应用捆绑,无需在源代码中写死,因此我们可以改变或替换他们,而无需对应用重新编译. 了解资源构成 参考阅读Android学习笔记(三八):资源res ...

  3. 【转】Pro Android学习笔记(二):开发环境:基础概念、连接真实设备、生命周期

    在Android学习笔记(二):安装环境中已经有相应的内容.看看何为新.这是在source网站上的Android架构图,和标准图没有区别,只是这张图颜色好看多了,录之.本笔记主要讲述Android开发 ...

  4. Android学习笔记进阶17之LinearGradient

    具体的看一下博文:Android学习笔记进阶15之Shader渲染 package xiaosi.BitmapShader; import android.app.Activity; import a ...

  5. Android学习笔记进阶16之BitmapShader

    <1>简介 具体的看一下博文:Android学习笔记进阶15之Shader渲染 public   BitmapShader(Bitmap bitmap,Shader.TileMode ti ...

  6. Android 学习笔记之Volley(七)实现Json数据加载和解析...

    学习内容: 1.使用Volley实现异步加载Json数据...   Volley的第二大请求就是通过发送请求异步实现Json数据信息的加载,加载Json数据有两种方式,一种是通过获取Json对象,然后 ...

  7. Android学习笔记进阶之在图片上涂鸦(能清屏)

    Android学习笔记进阶之在图片上涂鸦(能清屏) 2013-11-19 10:52 117人阅读 评论(0) 收藏 举报 HandWritingActivity.java package xiaos ...

  8. android学习笔记36——使用原始XML文件

    XML文件 android中使用XML文件,需要开发者手动创建res/xml文件夹. 实例如下: book.xml==> <?xml version="1.0" enc ...

  9. Android学习笔记之JSON数据解析

    转载:Android学习笔记44:JSON数据解析 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,为Web应用开发提供了一种 ...

随机推荐

  1. 35.自己实现vector模板库myvector

    myvector.h #pragma once //自己写的vector模板库 template <class T> class myvector { public: //构造 myvec ...

  2. EntityFramework学习笔记1--安装

    1.新建项目 2.工具=>NuGet程序包管理器=>程序包管理控制器 3.PM> Install-Package EntityFramework 安装EF

  3. 状态压缩dp初学__$Corn Fields$

    明天计划上是要刷状压,但是作为现在还不会状压的\(ruoruo\)来说是一件非常苦逼的事情,所以提前学了一下状压\(dp\). 鸣谢\(hmq\ juju\)的友情帮助 状态压缩动态规划 本博文的大体 ...

  4. java操作文件创建、删除

    java操作文件创建.删除: package test; import java.io.File; import java.io.IOException; import org.slf4j.Logge ...

  5. LeetCode(6)ZigZag Conversion

    题目如下: C++代码: #include <iostream> #include <string> using namespace std; class Solution { ...

  6. 事件处理:pull与push

    push:对应函数调用:属于发起方主动型 pull :对应消息循环:模型为信息池+事件循环+派发:属于接收者主动: 通常这种模式的角色对应于消息中心(事件派发中心). 观察者模式:变化+派发.

  7. Class.forName()用法详解 【转】

    来源  http://blog.csdn.net/kaiwii/article/details/7405761 主要功能 Class.forName(xxx.xx.xx)返回的是一个类 Class.f ...

  8. linux学习之多高并发服务器篇(三)

    UDP多播服务器 多播 组播组可以是永久的也可以是临时的.组播组地址中,有一部分由官方分配的,称为永久组播组.永久组播组保持不变的是它的ip地址,组中的成员构成可以发 生变化.永久组播组中成员的数量都 ...

  9. 【转】30分钟掌握 C#6

    [转]30分钟掌握 C#6 1. 只读自动属性(Read-only auto-properties) C# 6之前我们构建只读自动属性: public string FirstName { get; ...

  10. 洛谷 P1407 工资

    P1407 工资 题目描述 有一家世界级大企业,他们经过调查,发现了一个奇特的现象,竟然在自己的公司里,有超过一半的雇员,他们的工资完全相同! 公布了这项调查结果后,众多老板对于这一现象很感兴趣,他们 ...