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

得意犹堪夸世俗,诏黄新湿字如鸦。这篇文章主要讲述android图像处理系列之三-- 图片色调饱和度色相亮度处理相关的知识,希望能为你提供帮助。
原图:

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

文章图片


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

文章图片


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

二、主界面:
[java] view plain copy
  1. package  com.jacp.tone;    
  2.    
  3. import  java.util.ArrayList;    
  4.    
  5. import  android.app.Activity;    
  6. import  android.graphics.Bitmap;    
  7. import  android.graphics.BitmapFactory;    
  8. import  android.os.Bundle;    
  9. import  android.widget.ImageView;    
  10. import  android.widget.LinearLayout;    
  11. import  android.widget.SeekBar;    
  12. import  android.widget.SeekBar.OnSeekBarChangeListener;    
  13.    
  14. import  com.jacp.tone.view.ToneLayer;    
  15.    
  16. /** 
  17.   *  启动的主界面 
  18.   *  @author  [email  protected] 
  19.   * 
  20.   */   
  21. public  class  ImageToneActivity  extends  Activity  implements  OnSeekBarChangeListener  {   
  22.         private  ToneLayer  mToneLayer;    
  23.         private  ImageView  mImageView;    
  24.         private  Bitmap  mBitmap;    
  25.            
  26.         @Override   
  27.         public  void  onCreate(Bundle  savedInstanceState)  {   
  28.                 super.onCreate(savedInstanceState);    
  29.                 setContentView(R.layout.main);    
  30.                    
  31.                 init();    
  32.         }   
  33.            
  34.         private  void  init()   
  35.         {   
  36.                 mToneLayer  =  new  ToneLayer(this);    
  37.                    
  38.                 mBitmap  =  BitmapFactory.decodeResource(getResources(),  R.drawable.test);    
  39.                 mImageView  =  (ImageView)  findViewById(R.id.img_view);    
  40.                 mImageView.setImageBitmap(mBitmap);    
  41.                 ((LinearLayout)  findViewById(R.id.tone_view)).addView(mToneLayer.getParentView());    
  42.                    
  43.                 ArrayList< SeekBar>   seekBars  =  mToneLayer.getSeekBars();    
  44.                 for  (int  i  =  0,  size  =  seekBars.size();   i  <   size;   i++)   
  45.                 {   
  46.                         seekBars.get(i).setOnSeekBarChangeListener(this);    
  47.                 }   
  48.         }   
  49.    
  50.         @Override   
  51.         public  void  onProgressChanged(SeekBar  seekBar,  int  progress,   
  52.                         boolean  fromUser)  {   
  53.                 int  flag  =  (Integer)  seekBar.getTag();    
  54.                 switch  (flag)   
  55.                 {   
  56.                 case  ToneLayer.FLAG_SATURATION:   
  57.                         mToneLayer.setSaturation(progress);    
  58.                         break;    
  59.                 case  ToneLayer.FLAG_LUM:   
  60.                         mToneLayer.setLum(progress);    
  61.                         break;    
  62.                 case  ToneLayer.FLAG_HUE:   
  63.                         mToneLayer.setHue(progress);    
  64.                         break;    
  65.                 }   
  66.                    
  67.                 mImageView.setImageBitmap(mToneLayer.handleImage(mBitmap,  flag));    
  68.         }   
  69.    
  70.         @Override   
  71.         public  void  onStartTrackingTouch(SeekBar  seekBar)  {   
  72.                    
  73.         }   
  74.    
  75.         @Override   
  76.         public  void  onStopTrackingTouch(SeekBar  seekBar)  {   
  77.                    
  78.         }   
  79. }   
【android图像处理系列之三-- 图片色调饱和度色相亮度处理】
三、布局文件:
[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.            
    7.         < LinearLayout     
    8.                 android:layout_width="match_parent"   
    9.                 android:layout_height="match_parent"   
    10.                 android:orientation="vertical"  >    
    11.            
    12.                 < ImageView   
    13.                         android:layout_width="wrap_content"   
    14.                         android:layout_height="wrap_content"   
    15.                         android:layout_weight="1"   
    16.                         android:id="@+id/img_view"   
    17.                         android:layout_gravity="center"   
    18.                         />    
    19.                 < LinearLayout   
    20.                         android:layout_width="match_parent"   
    21.                         android:layout_height="wrap_content"   
    22.                         android:id="@+id/tone_view"   
    23.                         />    
    24.         < /LinearLayout>    
    25. < /ScrollView>  





    推荐阅读