zoukankan      html  css  js  c++  java
  • android图像处理系列之三--图片色调饱和度、色相、亮度处理

    原图:


    处理后:


    下面贴代码:

    一、图片处理层:

    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, 0, 0, paint); // 将颜色变化后的图片输出到新创建的位图区  
    251.         // 返回新的位图,也即调色处理后的图片  
    252.         return bmp;  
    253.     }  
    254.   
    255. }  


    二、主界面:

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


    三、布局文件:

      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> 
  • 相关阅读:
    hdu 2647 Reward
    hdu 2094 产生冠军
    hdu 3342 Legal or Not
    hdu 1285 确定比赛名次
    hdu 3006 The Number of set
    hdu 1429 胜利大逃亡(续)
    UVA 146 ID Codes
    UVA 131 The Psychic Poker Player
    洛谷 P2491消防 解题报告
    洛谷 P2587 [ZJOI2008]泡泡堂 解题报告
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/6722118.html
Copyright © 2011-2022 走看看