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

来源:互联网 发布:男款汉服款式知乎 编辑:程序博客网 时间:2024/05/01 17:30

 

原图:


处理后:


下面贴代码:

一、图片处理层:

[java] view plaincopyprint?
  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 maylian7700@126.com 
  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, 00, paint); // 将颜色变化后的图片输出到新创建的位图区  
  251.         // 返回新的位图,也即调色处理后的图片   
  252.         return bmp;  
  253.     }  
  254.   
  255. }  


二、主界面:

[java] view plaincopyprint?
  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 maylian7700@126.com 
  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. }  


三、布局文件:

[java] view plaincopyprint?
  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>  


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 ems档案丢了怎么办 ems 信 丢了怎么办 办快递代收点怎么办 淘宝退货退款取消怎么办 淘宝卖家不给退款怎么办 商家退货不退款怎么办 专卖店不给退怎么办 理发店顾客钱收少了怎么办 淘宝店铺搜不到怎么办 淘宝客服不在线怎么办 淘宝售后服务客服帮着卖家怎么办 老公一年找不到工作怎么办 淘宝店家跑了怎么办 淘宝卖家跑了怎么办啊 没发货退不了怎么办 微信上遇到诈骗怎么办 拼多多二级处罚怎么办 淘宝售后过了怎么办 遇到耍无赖的人怎么办 欠钱耍无赖得怎么办 借钱不还耍无赖怎么办 淘宝开食品店证件怎么办 手机卡掉了话费怎么办 手机变板砖怎么办 10086短信收不到怎么办 苹果手机成砖头怎么办 手机死砖了怎么办 苹果电脑成砖了怎么办 苹果误充游戏怎么办 话费如果交错了怎么办 联通充错号码怎么办 淘宝店铺假流量怎么办 空号交错话费怎么办 微信上被骗4800怎么办 移动手机号空号怎么办 微信充值充错号码对方是空号怎么办 买了运险费退货怎么办 手机玩吃鸡有点卡怎么办 微信手机充值充到空号怎么办 用微信交话费交错了怎么办 眼睫毛烫坏了怎么办