原图:

处理后:

下面贴代码:

一、图片处理层:

  1. package com.jacp.tone.view;
  2. import java.util.ArrayList;
  3. import android.content.Context;
  4. import android.graphics.Bitmap;
  5. import android.graphics.Canvas;
  6. import android.graphics.ColorMatrix;
  7. import android.graphics.ColorMatrixColorFilter;
  8. import android.graphics.Paint;
  9. import android.view.Gravity;
  10. import android.view.View;
  11. import android.widget.LinearLayout;
  12. import android.widget.SeekBar;
  13. import android.widget.SeekBar.OnSeekBarChangeListener;
  14. import android.widget.TextView;
  15. import com.jacp.tone.R;
  16. /**
  17. * 图片调色处理
  18. * @author maylian7700@126.com
  19. *
  20. */
  21. public class ToneLayer {
  22. /**
  23. * 饱和度标识
  24. */
  25. public static final int FLAG_SATURATION = 0x0;
  26. /**
  27. * 亮度标识
  28. */
  29. public static final int FLAG_LUM = 0x1;
  30. /**
  31. * 色相标识
  32. */
  33. public static final int FLAG_HUE = 0x2;
  34. /**
  35. * 饱和度
  36. */
  37. private TextView mSaturation;
  38. private SeekBar mSaturationBar;
  39. /**
  40. * 色相
  41. */
  42. private TextView mHue;
  43. private SeekBar mHueBar;
  44. /**
  45. * 亮度
  46. */
  47. private TextView mLum;
  48. private SeekBar mLumBar;
  49. private float mDensity;
  50. private static final int TEXT_WIDTH = 50;
  51. private LinearLayout mParent;
  52. private ColorMatrix mLightnessMatrix;
  53. private ColorMatrix mSaturationMatrix;
  54. private ColorMatrix mHueMatrix;
  55. private ColorMatrix mAllMatrix;
  56. /**
  57. * 亮度
  58. */
  59. private float mLumValue = 1F;
  60. /**
  61. * 饱和度
  62. */
  63. private float mSaturationValue = 0F;
  64. /**
  65. * 色相
  66. */
  67. private float mHueValue = 0F;
  68. /**
  69. * SeekBar的中间值
  70. */
  71. private static final int MIDDLE_VALUE = 127;
  72. /**
  73. * SeekBar的最大值
  74. */
  75. private static final int MAX_VALUE = 255;
  76. private ArrayList<SeekBar> mSeekBars = new ArrayList<SeekBar>();
  77. public ToneLayer(Context context) {
  78. init(context);
  79. }
  80. private void init(Context context) {
  81. mDensity = context.getResources().getDisplayMetrics().density;
  82. mSaturation = new TextView(context);
  83. mSaturation.setText(R.string.saturation);
  84. mHue = new TextView(context);
  85. mHue.setText(R.string.contrast);
  86. mLum = new TextView(context);
  87. mLum.setText(R.string.lightness);
  88. mSaturationBar = new SeekBar(context);
  89. mHueBar = new SeekBar(context);
  90. mLumBar = new SeekBar(context);
  91. mSeekBars.add(mSaturationBar);
  92. mSeekBars.add(mHueBar);
  93. mSeekBars.add(mLumBar);
  94. for (int i = 0, size = mSeekBars.size(); i < size; i++) {
  95. SeekBar seekBar = mSeekBars.get(i);
  96. seekBar.setMax(MAX_VALUE);
  97. seekBar.setProgress(MIDDLE_VALUE);
  98. seekBar.setTag(i);
  99. }
  100. LinearLayout saturation = new LinearLayout(context);
  101. saturation.setOrientation(LinearLayout.HORIZONTAL);
  102. saturation.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
  103. LinearLayout.LayoutParams txtLayoutparams = new LinearLayout.LayoutParams((int) (TEXT_WIDTH * mDensity), LinearLayout.LayoutParams.MATCH_PARENT);
  104. mSaturation.setGravity(Gravity.CENTER);
  105. saturation.addView(mSaturation, txtLayoutparams);
  106. LinearLayout.LayoutParams seekLayoutparams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
  107. saturation.addView(mSaturationBar, seekLayoutparams);
  108. LinearLayout hue = new LinearLayout(context);
  109. hue.setOrientation(LinearLayout.HORIZONTAL);
  110. hue.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
  111. mHue.setGravity(Gravity.CENTER);
  112. hue.addView(mHue, txtLayoutparams);
  113. hue.addView(mHueBar, seekLayoutparams);
  114. LinearLayout lum = new LinearLayout(context);
  115. lum.setOrientation(LinearLayout.HORIZONTAL);
  116. lum.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
  117. mLum.setGravity(Gravity.CENTER);
  118. lum.addView(mLum, txtLayoutparams);
  119. lum.addView(mLumBar, seekLayoutparams);
  120. mParent = new LinearLayout(context);
  121. mParent.setOrientation(LinearLayout.VERTICAL);
  122. mParent.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
  123. mParent.addView(saturation);
  124. mParent.addView(hue);
  125. mParent.addView(lum);
  126. }
  127. public View getParentView() {
  128. return mParent;
  129. }
  130. /**
  131. * 设置饱和度值
  132. * @param saturation
  133. */
  134. public void setSaturation(int saturation) {
  135. mSaturationValue = saturation * 1.0F / MIDDLE_VALUE;
  136. }
  137. /**
  138. * 设置色相值
  139. * @param hue
  140. */
  141. public void setHue(int hue) {
  142. mHueValue = hue * 1.0F / MIDDLE_VALUE;
  143. }
  144. /**
  145. * 设置亮度值
  146. * @param lum
  147. */
  148. public void setLum(int lum) {
  149. mLumValue = (lum - MIDDLE_VALUE) * 1.0F / MIDDLE_VALUE * 180;
  150. }
  151. public ArrayList<SeekBar> getSeekBars()
  152. {
  153. return mSeekBars;
  154. }
  155. /**
  156. *
  157. * @param flag
  158. *            比特位0 表示是否改变色相,比位1表示是否改变饱和度,比特位2表示是否改变明亮度
  159. */
  160. public Bitmap handleImage(Bitmap bm, int flag) {
  161. Bitmap bmp = Bitmap.createBitmap(bm.getWidth(), bm.getHeight(),
  162. Bitmap.Config.ARGB_8888);
  163. // 创建一个相同尺寸的可变的位图区,用于绘制调色后的图片
  164. Canvas canvas = new Canvas(bmp); // 得到画笔对象
  165. Paint paint = new Paint(); // 新建paint
  166. paint.setAntiAlias(true); // 设置抗锯齿,也即是边缘做平滑处理
  167. if (null == mAllMatrix) {
  168. mAllMatrix = new ColorMatrix();
  169. }
  170. if (null == mLightnessMatrix) {
  171. mLightnessMatrix = new ColorMatrix(); // 用于颜色变换的矩阵,android位图颜色变化处理主要是靠该对象完成
  172. }
  173. if (null == mSaturationMatrix) {
  174. mSaturationMatrix = new ColorMatrix();
  175. }
  176. if (null == mHueMatrix) {
  177. mHueMatrix = new ColorMatrix();
  178. }
  179. switch (flag) {
  180. case FLAG_HUE: // 需要改变色相
  181. mHueMatrix.reset();
  182. mHueMatrix.setScale(mHueValue, mHueValue, mHueValue, 1); // 红、绿、蓝三分量按相同的比例,最后一个参数1表示透明度不做变化,此函数详细说明参考
  183. // // android
  184. // doc
  185. break;
  186. case FLAG_SATURATION: // 需要改变饱和度
  187. // saturation 饱和度值,最小可设为0,此时对应的是灰度图(也就是俗话的“黑白图”),
  188. // 为1表示饱和度不变,设置大于1,就显示过饱和
  189. mSaturationMatrix.reset();
  190. mSaturationMatrix.setSaturation(mSaturationValue);
  191. break;
  192. case FLAG_LUM: // 亮度
  193. // hueColor就是色轮旋转的角度,正值表示顺时针旋转,负值表示逆时针旋转
  194. mLightnessMatrix.reset(); // 设为默认值
  195. mLightnessMatrix.setRotate(0, mLumValue); // 控制让红色区在色轮上旋转的角度
  196. mLightnessMatrix.setRotate(1, mLumValue); // 控制让绿红色区在色轮上旋转的角度
  197. mLightnessMatrix.setRotate(2, mLumValue); // 控制让蓝色区在色轮上旋转的角度
  198. // 这里相当于改变的是全图的色相
  199. break;
  200. }
  201. mAllMatrix.reset();
  202. mAllMatrix.postConcat(mHueMatrix);
  203. mAllMatrix.postConcat(mSaturationMatrix); // 效果叠加
  204. mAllMatrix.postConcat(mLightnessMatrix); // 效果叠加
  205. paint.setColorFilter(new ColorMatrixColorFilter(mAllMatrix));// 设置颜色变换效果
  206. canvas.drawBitmap(bm, 0, 0, paint); // 将颜色变化后的图片输出到新创建的位图区
  207. // 返回新的位图,也即调色处理后的图片
  208. return bmp;
  209. }
  210. }

二、主界面:

  1. package com.jacp.tone;
  2. import java.util.ArrayList;
  3. import android.app.Activity;
  4. import android.graphics.Bitmap;
  5. import android.graphics.BitmapFactory;
  6. import android.os.Bundle;
  7. import android.widget.ImageView;
  8. import android.widget.LinearLayout;
  9. import android.widget.SeekBar;
  10. import android.widget.SeekBar.OnSeekBarChangeListener;
  11. import com.jacp.tone.view.ToneLayer;
  12. /**
  13. * 启动的主界面
  14. * @author maylian7700@126.com
  15. *
  16. */
  17. public class ImageToneActivity extends Activity implements OnSeekBarChangeListener {
  18. private ToneLayer mToneLayer;
  19. private ImageView mImageView;
  20. private Bitmap mBitmap;
  21. @Override
  22. public void onCreate(Bundle savedInstanceState) {
  23. super.onCreate(savedInstanceState);
  24. setContentView(R.layout.main);
  25. init();
  26. }
  27. private void init()
  28. {
  29. mToneLayer = new ToneLayer(this);
  30. mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.test);
  31. mImageView = (ImageView) findViewById(R.id.img_view);
  32. mImageView.setImageBitmap(mBitmap);
  33. ((LinearLayout) findViewById(R.id.tone_view)).addView(mToneLayer.getParentView());
  34. ArrayList<SeekBar> seekBars = mToneLayer.getSeekBars();
  35. for (int i = 0, size = seekBars.size(); i < size; i++)
  36. {
  37. seekBars.get(i).setOnSeekBarChangeListener(this);
  38. }
  39. }
  40. @Override
  41. public void onProgressChanged(SeekBar seekBar, int progress,
  42. boolean fromUser) {
  43. int flag = (Integer) seekBar.getTag();
  44. switch (flag)
  45. {
  46. case ToneLayer.FLAG_SATURATION:
  47. mToneLayer.setSaturation(progress);
  48. break;
  49. case ToneLayer.FLAG_LUM:
  50. mToneLayer.setLum(progress);
  51. break;
  52. case ToneLayer.FLAG_HUE:
  53. mToneLayer.setHue(progress);
  54. break;
  55. }
  56. mImageView.setImageBitmap(mToneLayer.handleImage(mBitmap, flag));
  57. }
  58. @Override
  59. public void onStartTrackingTouch(SeekBar seekBar) {
  60. }
  61. @Override
  62. public void onStopTrackingTouch(SeekBar seekBar) {
  63. }
  64. }

三、布局文件:

    1. <?xml version="1.0" encoding="utf-8"?>
    2. <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    3. android:layout_width="match_parent"
    4. android:layout_height="match_parent"
    5. >
    6. <LinearLayout
    7. android:layout_width="match_parent"
    8. android:layout_height="match_parent"
    9. android:orientation="vertical" >
    10. <ImageView
    11. android:layout_width="wrap_content"
    12. android:layout_height="wrap_content"
    13. android:layout_weight="1"
    14. android:id="@+id/img_view"
    15. android:layout_gravity="center"
    16. />
    17. <LinearLayout
    18. android:layout_width="match_parent"
    19. android:layout_height="wrap_content"
    20. android:id="@+id/tone_view"
    21. />
    22. </LinearLayout>
    23. </ScrollView>

android图像处理系列之三-- 图片色调饱和度、色相、亮度处理的更多相关文章

  1. android图像处理系列之三--图片色调饱和度、色相、亮度处理

    原图: 处理后: 下面贴代码: 一.图片处理层: package com.jacp.tone.view; import java.util.ArrayList; import android.cont ...

  2. android图像处理系列之四-- 给图片添加边框(上)

    图片处理时,有时需要为图片加一些边框,下面介绍一种为图片添加简单边框的方法. 基本思路是:将边框图片裁剪成八张小图片(图片大小最好一致,不然后面处理会很麻烦),分别对应左上角,左边,左下角,下边,右下 ...

  3. android图像处理系列之五-- 给图片添加边框(中)

    前面一篇讲到给图片加边框的方式,只能给图片加一些有规则的边框,如果想加一些比较精美的效果,就有点麻烦了.下面就给出解决这个问题的思路. 思路是:一些比较精美的花边图片我们是很难用代码控制,就目前本人水 ...

  4. android图像处理系列之四--给图片添加边框(上)

    图片处理时,有时需要为图片加一些边框,下面介绍一种为图片添加简单边框的方法. 基本思路是:将边框图片裁剪成八张小图片(图片大小最好一致,不然后面处理会很麻烦),分别对应左上角,左边,左下角,下边,右下 ...

  5. android图像处理系列之五--给图片添加边框(中)

    前面一篇讲到给图片加边框的方式,只能给图片加一些有规则的边框,如果想加一些比较精美的效果,就有点麻烦了.下面就给出解决这个问题的思路. 思路是:一些比较精美的花边图片我们是很难用代码控制,就目前本人水 ...

  6. android图像处理系列之七--图片涂鸦,水印-图片叠加

    图片涂鸦和水印其实是一个功能,实现的方式是一样的,就是一张大图片和一张小点图片叠加即可.前面在android图像处理系列之六--给图片添加边框(下)-图片叠加中也讲到了图片叠加,里面实现的原理是直接操 ...

  7. android 图像处理系列合集

    为了便于大家对滤镜算法的学习,以后发布的图像处理滤镜系列帖子会在这里汇总,本人第一次写合集,写得不好的地方大家请见谅,手头上虽然有一些滤镜的算法,但是大多不是android版的,教程里的代码大多是我借 ...

  8. iOS有关图片处理的总结 (四)------图片的饱和度,亮度,对照度。

    在做图片处理的时候.会遇到调节图片的饱和度的问题,这里就要用到Core Image这个框架,Core Image是一个非常强大的框架. 它能够让你简单地应用各种滤镜来处理图像,比方改动鲜艳程度, 色泽 ...

  9. android图像处理系列之六-- 给图片添加边框(下)-图片叠加

    前面介绍了一种用透明图片叠加的方式添加花边边框,下面将介绍另外一种图片叠加添加花边边框的方式.前面方法有一个缺点,就是做成PNG图片,图片体积会很大,不是一般的大,比同样的JPG大三倍多,如果项目可以 ...

随机推荐

  1. BZOJ 1251 Splay维护序列

    思路: splay维护序列的裸题 啊woc调了一天 感谢yzy大佬的模板-- //By SiriusRen #include <cstdio> #include <cstring&g ...

  2. CheckException和RuntimeException

    java文档中对RuntimeException的定义是: RuntimeException 是那些可能在 Java 虚拟机正常运行期间抛出的异常的超类. 可能在执行方法期间抛出但未被捕获的 Runt ...

  3. PostgreSQL Replication之第四章 设置异步复制(8)

    4.8 处理时间线 时间线是一个您必须要知道的一个重要的概念,尤其是当您规划一个大型的设置的时候. 那么,什么是时间线呢?事实上,它是XLOG的一个分支.正常情况下,刚设置的一个数据库实例使用的时间线 ...

  4. Signal programming

    Signal programming is used in the same sense as dataflow programming, and is similar to event-driven ...

  5. 十五 Canny边缘检测算法

    一.Canny算法介绍 Canny 的目标是找到一个最优的边缘检测算法,最优边缘检测的含义是: 好的检测- 算法能够尽可能多地标识出图像中的实际边缘. 好的定位- 标识出的边缘要尽可能与实际图像中的实 ...

  6. POJ1201Intervals(差分约束)

    题意 给出数轴上的n个区间[ai,bi],每个区间都是连续的int区间. 现在要在数轴上任意取一堆元素,构成一个元素集合V 要求每个区间[ai,bi]和元素集合V的交集至少有ci不同的元素 求集合V最 ...

  7. python常用函数库收集。

    学习过Python都知道python中有很多库.python本身就是万能胶水,众多强大的库/模块正是它的优势. 收集一些Python常用的函数库,方便大家选择要学习的库,也方便自己学习收集,熟悉运用好 ...

  8. python语法学习笔记

    函数的参数   定义函数的时候,我们把参数的名字和位置确定下来,函数的接口定义就完成了.对于函数的调用者来说,只需要知道如何传递正确的参数,以及函数将返回什么样的值就够了,函数内部的复杂逻辑被封装起来 ...

  9. Apache CXF实战之二 集成Sping与Web容器

    本文链接:http://blog.csdn.net/kongxx/article/details/7525481 Apache CXF实战之一 Hello World Web Service 书接上文 ...

  10. 13 hbase源码系列(十三)缓存机制MemStore与Block Cache

    这一章讲hbase的缓存机制,这里面涉及的内容也是比较多,呵呵,我理解中的缓存是保存在内存中的特定的便于检索的数据结构就是缓存. 之前在讲put的时候,put是被添加到Store里面,这个Store是 ...