在Android中,对图像进行颜色方面的处理,如黑白老照片、泛黄旧照片、高对比度、低饱和度等效果,都可以通过使用颜色矩阵(ColorMatrix)来实现。

1.颜色矩阵(ColorMatrix)介绍

  颜色矩阵M是一个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 颜色矩阵M

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

图2 颜色分量矩阵C

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

图3 颜色分量矩阵计算公式

  由此可见,通过颜色矩阵修改了原图像的RGBA值,从而达到了改变图片颜色效果的目的。并且,通过如图3所示的运算可知,颜色矩阵M的第一行参数abcde决定了图像的红色成分,第二行参数fghij决定了图像的绿色成分,第三行参数klmno决定了图像的蓝色成分,第四行参数pqrst决定了图像的透明度,第五列参数ejot是颜色的偏移量。

  通常,改变颜色分量时可以通过修改第5列的颜色偏移量来实现,如图4所示的颜色矩阵M1,通过计算后可以得知该颜色矩阵的作用是使图像的红色分量和绿色分量均增加100,这样的效果就是图片泛黄(因为红色与绿色混合后得到黄色)。

图4 颜色矩阵M1

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

图5 颜色矩阵M2

2.图像颜色处理实例

  了解了颜色矩阵的工作原理之后,我们就可以使用颜色矩阵对图片进行处理了。

  布局代码:

  

<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 }

效果图:

android把彩色图像变成灰度图(黑白)

代码:

public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ImageView iv = new ImageView(this);
        setContentView(iv);
        Bitmap originImg = BitmapFactory.decodeResource(getResources(), R.drawable.painter);
        Bitmap grayImg = Bitmap.createBitmap(originImg.getWidth(), originImg.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(grayImg);
        Paint paint = new Paint();
        ColorMatrix colorMatrix = new ColorMatrix();
        colorMatrix.setSaturation(0);
        ColorMatrixColorFilter colorMatrixFilter = new ColorMatrixColorFilter(colorMatrix);
        paint.setColorFilter(colorMatrixFilter);
        canvas.drawBitmap(originImg, 0, 0, paint);
        iv.setImageBitmap(grayImg);
    }
}

主要是 colorMatrix.setSaturation(0);这一行代码的作用。

效果图,还是刚才的彩色图处理后的结果:

黑白老照片、泛黄旧照片、高对比度、低饱和度等效果

泛红效果



高对比度、高饱和度、色相变换等图片处理效果

Android ColorMatrix类图像颜色处理-黑白老照片、泛黄旧照片、高对比度等效果的更多相关文章

  1. Android学习笔记之图像颜色处理(ColorMatrix)

    对图像进行颜色方面的处理,通过使用颜色矩阵(ColorMatrix)来实现.从而可以达到很多特效如黑白老照片.泛黄旧照片等等. 1.颜色矩阵(ColorMatrix) 这里有详细的介绍:http:// ...

  2. Android图像格式类及图像转换方法

    Android图像格式类及图像转换方法介绍 一款软件的开发和图像密切相关,特别是移动应用程序,在视觉效果等方面是至关重要的,因为这直接关系到用户的体验效果.在Android程序开发的过程中,了解存在哪 ...

  3. Android 使用ColorMatrix改变图片颜色

    原文链接:http://blog.csdn.net/janice0529/article/details/49207939 ColorMatrix的颜色矩阵介绍 颜色矩阵M是一个5*4的矩阵,在And ...

  4. Android Matrix类以及ColorMatri

    引自:http://www.chinabaike.com/t/37396/2014/0624/2556217.html Android Matrix类以及ColorMatrix类详解 最近在系统学习了 ...

  5. Android资源之图像资源(图层图像资源)

    曾经看别人的程序的drawable目录里有xml资源,说实话第一次见到这种xml图像资源时,我真心不知道是干什么的.抽出时间学习了一下图像资源.才了解了这类图像资源的妙用. 以下我来分享一下这部分知识 ...

  6. android Activity类中的finish()、onDestory()和System.exit(0) 三者的区别

    android Activity类中的finish().onDestory()和System.exit(0) 三者的区别 Activity.finish() Call this when your a ...

  7. Codrops 实验:使用 Vibrant.js 提取图像颜色

    Codrops 分享了一个有趣的颜色提取实验.这个想法是创建图像的调色板,既有图像本身的潜移默化的影响,也有一些花哨的颜色延伸.通过使用 Vibrant.js 来提取图像中的颜色,并通过 CSS 过滤 ...

  8. Android中解决图像解码导致的OOM问题

    Android中解决图像解码导致的OOM问题 原文链接:http://blog.csdn.net/zjl5211314/article/details/7042017

  9. Android 服务类Service 的详细学习

    http://blog.csdn.net/vipzjyno1/article/details/26004831 Android服务类Service学习四大组建   目录(?)[+] 什么是服务 服务有 ...

随机推荐

  1. 【无语凝噎(wordless)】

    ·题目:         西施与范蠡泛舟而去……不对,场景不对,咳咳.在甄嬛前往蓬莱洲之前,她与皇上在碧桐书院告别.为了这可能会长达数月的离别,两个人都似乎有很多话要对对方说,却都无语凝噎.这时,皇上 ...

  2. 实现PC视频播放最强画质教程( Potplayer播放器+MADVR插件)【转】

    转自:http://www.hangge.com/blog/cache/detail_1461.html 一.MADVR介绍 MADVR 是一款超强的视频插件,其配合高清播放软件,可以做到目前 PC  ...

  3. 勤拂拭软件系列教程 之 Android开发之旅

    勤拂拭软件工作室持续推出Android开发系列教程与案例,供广大朋友分享交流技术经验,帮助喜欢Android的朋友们学习进步: 1. 勤拂拭软件Android开发之旅(1) 之 Android 开发环 ...

  4. JSONObject转换分析

    net.sf.json.JSONObject采用反射的方式,对POJO进行转换.JSONObject类实现了JSON.Map和Comparable接口,如下: class JSONObject ext ...

  5. 手机上的ROM与RAM

    ROM:read only memory翻译为只读存储器. RAM:read access memory翻译为随机存储器. 下面是一张手机的配置参数表. 简单来说,RAM就是真正意义上的内存,而ROM ...

  6. Python之作业购物车

    作业之购物车优化 购物车优化要求如下: 用户入口: 启动程序后,输入用户名密码后,如果是第一次登录,让用户输入工资,然后打印商品列表 允许用户根据商品编号购买商品 用户选择商品后,检测余额是否够,够就 ...

  7. JSON概述

    错误理解:         一直以为JSON就是对象,拥有跟js对象类似的特征:{key:value}形式, 以至于在自己的思维定式中就出现了一种很可怕的情景:居然不知道怎么去解释习以为常的json是 ...

  8. JS 中判断空值 undefined 和 null

    1.JS 中如何判断 undefined JavaScript 中有两个特殊数据类型:undefined 和 null,下节介绍了 null 的判断,下面谈谈 undefined 的判断. 以下是不正 ...

  9. 72. Edit Distance(困难,确实挺难的,但很经典,双序列DP问题)

    Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2 ...

  10. Go 处理yaml类型的配置文件

    先说一下,这里用到了很多关于反射类型的功能,可能刚开始看代码,如果对反射不熟悉的可能会不是非常清晰,但是同时也是为了更好的理解golang中的反射,同时如果后面想在代码中可以直接从我的git地址get ...