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

原图:

处理后:

下面贴代码:

一、图片处理层:

[java] view plain copy

  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 [email protected]
  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. }

二、主界面:

[java] view plain copy

  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 [email protected]
  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. }

三、布局文件:

[java] view plain copy

    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>
时间: 2024-10-04 07:54:10

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

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

原图: 处理后: 下面贴代码: 一.图片处理层: [java] view plaincopy package com.jacp.tone.view; import java.util.ArrayList; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.ColorMatrix; import android

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

图片涂鸦和水印其实是一个功能,实现的方式是一样的,就是一张大图片和一张小点图片叠加即可.前面在android图像处理系列之六--给图片添加边框(下)-图片叠加中也讲到了图片叠加,里面实现的原理是直接操作像素点.下面给出别外一种方式让图片叠加--用Canvas处理图片,canvas已经封装好了,直接调用就行. 下面看效果: += 代码: [java] view plain copy /** * 组合涂鸦图片和源图片 * @param src 源图片 * @param watermark 涂鸦图片

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

前面一篇讲到给图片加边框的方式,只能给图片加一些有规则的边框,如果想加一些比较精美的效果,就有点麻烦了.下面就给出解决这个问题的思路. 思路是:一些比较精美的花边图片我们是很难用代码控制,就目前本人水平是达不到,不排除牛人,再说了PS那些效果都是程序员做出来,肯定有实现的方法,这可能就要涉及很复杂的图形学.扯远了,接来说怎么用那些精美的花边做为图片的边框.简单的方式是用两张图片叠加.最简单的一种是本文介绍的,用透明的PNG格式图片.因为Android是支持PNG图片处理的,而且PNG图片有透明度

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

图片处理时,有时需要为图片加一些边框,下面介绍一种为图片添加简单边框的方法. 基本思路是:将边框图片裁剪成八张小图片(图片大小最好一致,不然后面处理会很麻烦),分别对应左上角,左边,左下角,下边,右下角,右边,右上角,上边,其中左右上下只需要一个有效长度,就像重写水平进度条一样,只需要一个有效的长度,然后平铺,就达到了最后想要的效果,不错,左右上下边采用的也是这样的思路.也可以将八张图片组合在一起,然后读取整张图片,用代码裁剪,下面会给出相应的代码.下面的代码主要是给出第一种方法,后一种给出代码

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

图片处理时,有时需要为图片加一些边框,下面介绍一种为图片添加简单边框的方法. 基本思路是:将边框图片裁剪成八张小图片(图片大小最好一致,不然后面处理会很麻烦),分别对应左上角,左边,左下角,下边,右下角,右边,右上角,上边,其中左右上下只需要一个有效长度,就像重写水平进度条一样,只需要一个有效的长度,然后平铺,就达到了最后想要的效果,不错,左右上下边采用的也是这样的思路.也可以将八张图片组合在一起,然后读取整张图片,用代码裁剪,下面会给出相应的代码.下面的代码主要是给出第一种方法,后一种给出代码

android 图像处理系列合集

为了便于大家对滤镜算法的学习,以后发布的图像处理滤镜系列帖子会在这里汇总,本人第一次写合集,写得不好的地方大家请见谅,手头上虽然有一些滤镜的算法,但是大多不是android版的,教程里的代码大多是我借鉴其他语言的算法转换而成的,效率上还存在优化的空间,大家可以自行优化.有些网友说代码能看懂,但是里面的某些数值不知道是怎么计算出来的,说实话有些数值我不查资料我也不是很清楚,但是当我需要知道的时候我也会慢慢查阅算法的核心思想,很多参数由此而来.同时也希望大家养成不懂就查的习惯. android 图像

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

前面介绍了一种用透明图片叠加的方式添加花边边框,下面将介绍另外一种图片叠加添加花边边框的方式.前面方法有一个缺点,就是做成PNG图片,图片体积会很大,不是一般的大,比同样的JPG大三倍多,如果项目可以忽略包的大小,那么可以用前种处理方式,本文讲到的虽然可以减小图片的体积,但处理较复杂,而且本人研究的还不是很成熟.本文就是针对JPG边框处理,但缺点是还不够成熟,仅提供思路. 思路:可以将边框做成JPG图片,没有边框的地方,一般都是中间区域调成特殊颜色,比如黑色.在两张图片叠加的时候,对边框图片做特

RDLC系列之三 图片显示

一.头像效果 二.步骤 1.后台代码添加图片路径参数 2.在报表中添加图片路径参数picPath,添加图片控件,并设置选择源为外部.指定参数picPath 参考文章: http://www.cnblogs.com/jobin/articles/1152060.html 向 ReportViewer 报表中添加图像 图像是一种包含对存储在报表服务器上.嵌入在报表中或存储在数据库中的图像的引用的报表项.图像可以是报表中显示一次的徽标或图片,也可以是数据行中重复显示的图片.还可以将图像用作某些报表项的

Android RakNet 系列之三 移植Portaudio

简介 PortAudio 是一个跨平台采集和播放音频的开源库,不过尚未支持Android平台,笔者决定让PortAudio支持Android.Android上,处理音频的库是OpenSL ES,从API 9开始支持的技术,通过这个标准,Android已经完全可以在native层采集和播放音频.换句话说,PortAudio支持Android,也就是支持OpenSL ES. 详情 Opensl es penSL ES 是无授权费.跨平台.针对嵌入式系统精心优化的硬件音频加速API.它为嵌入式移动多媒