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

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

               

原图:


处理后:


下面贴代码:

一、图片处理层:

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.graphics.ColorMatrixColorFilter;import android.graphics.Paint;import android.view.Gravity;import android.view.View;import android.widget.LinearLayout;import android.widget.SeekBar;import android.widget.SeekBar.OnSeekBarChangeListener;import android.widget.TextView;import com.jacp.tone.R;/** * 图片调色处理 * @author [email protected] * */public class ToneLayer {  /**  * 饱和度标识  */ public static final int FLAG_SATURATION = 0x0;  /**  * 亮度标识  */ public static final int FLAG_LUM = 0x1;  /**  * 色相标识  */ public static final int FLAG_HUE = 0x2;  /**  * 饱和度  */ private TextView mSaturation; private SeekBar mSaturationBar; /**  * 色相  */ private TextView mHue; private SeekBar mHueBar; /**  * 亮度  */ private TextView mLum; private SeekBar mLumBar; private float mDensity; private static final int TEXT_WIDTH = 50private LinearLayout mParent; private ColorMatrix mLightnessMatrix; private ColorMatrix mSaturationMatrix; private ColorMatrix mHueMatrix; private ColorMatrix mAllMatrix; /**  * 亮度  */ private float mLumValue = 1F/**  * 饱和度  */ private float mSaturationValue = 0F/**  * 色相  */ private float mHueValue = 0F;  /**  * SeekBar的中间值  */ private static final int MIDDLE_VALUE = 127;  /**  * SeekBar的最大值  */ private static final int MAX_VALUE = 255;  private ArrayList<SeekBar> mSeekBars = new ArrayList<SeekBar>(); public ToneLayer(Context context) {  init(context); } private void init(Context context) {  mDensity = context.getResources().getDisplayMetrics().density;  mSaturation = new TextView(context);  mSaturation.setText(R.string.saturation);  mHue = new TextView(context);  mHue.setText(R.string.contrast);  mLum = new TextView(context);  mLum.setText(R.string.lightness);    mSaturationBar = new SeekBar(context);  mHueBar = new SeekBar(context);  mLumBar = new SeekBar(context);    mSeekBars.add(mSaturationBar);  mSeekBars.add(mHueBar);  mSeekBars.add(mLumBar);    for (int i = 0, size = mSeekBars.size(); i < size; i++) {   SeekBar seekBar = mSeekBars.get(i);   seekBar.setMax(MAX_VALUE);   seekBar.setProgress(MIDDLE_VALUE);   seekBar.setTag(i);  }  LinearLayout saturation = new LinearLayout(context);  saturation.setOrientation(LinearLayout.HORIZONTAL);  saturation.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));  LinearLayout.LayoutParams txtLayoutparams = new LinearLayout.LayoutParams((int) (TEXT_WIDTH * mDensity), LinearLayout.LayoutParams.MATCH_PARENT);  mSaturation.setGravity(Gravity.CENTER);  saturation.addView(mSaturation, txtLayoutparams);  LinearLayout.LayoutParams seekLayoutparams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);  saturation.addView(mSaturationBar, seekLayoutparams);  LinearLayout hue = new LinearLayout(context);  hue.setOrientation(LinearLayout.HORIZONTAL);  hue.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));  mHue.setGravity(Gravity.CENTER);  hue.addView(mHue, txtLayoutparams);  hue.addView(mHueBar, seekLayoutparams);  LinearLayout lum = new LinearLayout(context);  lum.setOrientation(LinearLayout.HORIZONTAL);  lum.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));  mLum.setGravity(Gravity.CENTER);  lum.addView(mLum, txtLayoutparams);  lum.addView(mLumBar, seekLayoutparams);  mParent = new LinearLayout(context);  mParent.setOrientation(LinearLayout.VERTICAL);  mParent.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));  mParent.addView(saturation);  mParent.addView(hue);  mParent.addView(lum); } public View getParentView() {  return mParent; } /**  * 设置饱和度值  * @param saturation  */ public void setSaturation(int saturation) {  mSaturationValue = saturation * 1.0F / MIDDLE_VALUE; } /**  * 设置色相值  * @param hue  */ public void setHue(int hue) {  mHueValue = hue * 1.0F / MIDDLE_VALUE; } /**  * 设置亮度值  * @param lum  */ public void setLum(int lum) {  mLumValue = (lum - MIDDLE_VALUE) * 1.0F / MIDDLE_VALUE * 180; } public ArrayList<SeekBar> getSeekBars() {  return mSeekBars; } /**  *   * @param flag  *            比特位0 表示是否改变色相,比位1表示是否改变饱和度,比特位2表示是否改变明亮度  */ public Bitmap handleImage(Bitmap bm, int flag) {  Bitmap bmp = Bitmap.createBitmap(bm.getWidth(), bm.getHeight(),    Bitmap.Config.ARGB_8888);  // 创建一个相同尺寸的可变的位图区,用于绘制调色后的图片  Canvas canvas = new Canvas(bmp); // 得到画笔对象  Paint paint = new Paint(); // 新建paint  paint.setAntiAlias(true); // 设置抗锯齿,也即是边缘做平滑处理  if (null == mAllMatrix) {   mAllMatrix = new ColorMatrix();  }  if (null == mLightnessMatrix) {   mLightnessMatrix = new ColorMatrix(); // 用于颜色变换的矩阵,android位图颜色变化处理主要是靠该对象完成  }  if (null == mSaturationMatrix) {   mSaturationMatrix = new ColorMatrix();  }  if (null == mHueMatrix) {   mHueMatrix = new ColorMatrix();  }  switch (flag) {  case FLAG_HUE: // 需要改变色相   mHueMatrix.reset();   mHueMatrix.setScale(mHueValue, mHueValue, mHueValue, 1); // 红、绿、蓝三分量按相同的比例,最后一个参数1表示透明度不做变化,此函数详细说明参考   // // android   // doc   break;  case FLAG_SATURATION: // 需要改变饱和度   // saturation 饱和度值,最小可设为0,此时对应的是灰度图(也就是俗话的“黑白图”),   // 为1表示饱和度不变,设置大于1,就显示过饱和   mSaturationMatrix.reset();   mSaturationMatrix.setSaturation(mSaturationValue);   break;  case FLAG_LUM: // 亮度   // hueColor就是色轮旋转的角度,正值表示顺时针旋转,负值表示逆时针旋转   mLightnessMatrix.reset(); // 设为默认值   mLightnessMatrix.setRotate(0, mLumValue); // 控制让红色区在色轮上旋转的角度   mLightnessMatrix.setRotate(1, mLumValue); // 控制让绿红色区在色轮上旋转的角度   mLightnessMatrix.setRotate(2, mLumValue); // 控制让蓝色区在色轮上旋转的角度   // 这里相当于改变的是全图的色相   break;  }  mAllMatrix.reset();  mAllMatrix.postConcat(mHueMatrix);  mAllMatrix.postConcat(mSaturationMatrix); // 效果叠加  mAllMatrix.postConcat(mLightnessMatrix); // 效果叠加  paint.setColorFilter(new ColorMatrixColorFilter(mAllMatrix));// 设置颜色变换效果  canvas.drawBitmap(bm, 0, 0, paint); // 将颜色变化后的图片输出到新创建的位图区  // 返回新的位图,也即调色处理后的图片  return bmp; }}


二、主界面:

package com.jacp.tone;import java.util.ArrayList;import android.app.Activity;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.Bundle;import android.widget.ImageView;import android.widget.LinearLayout;import android.widget.SeekBar;import android.widget.SeekBar.OnSeekBarChangeListener;import com.jacp.tone.view.ToneLayer;/** * 启动的主界面 * @author [email protected] * */public class ImageToneActivity extends Activity implements OnSeekBarChangeListener private ToneLayer mToneLayer; private ImageView mImageView; private Bitmap mBitmap;     @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);                init();    }        private void init()    {     mToneLayer = new ToneLayer(this);                mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.test);        mImageView = (ImageView) findViewById(R.id.img_view);        mImageView.setImageBitmap(mBitmap);        ((LinearLayout) findViewById(R.id.tone_view)).addView(mToneLayer.getParentView());                ArrayList<SeekBar> seekBars = mToneLayer.getSeekBars();        for (int i = 0, size = seekBars.size(); i < size; i++)        {         seekBars.get(i).setOnSeekBarChangeListener(this);        }    } @Override public void onProgressChanged(SeekBar seekBar, int progress,   boolean fromUser) {  int flag = (Integer) seekBar.getTag();  switch (flag)  {  case ToneLayer.FLAG_SATURATION:   mToneLayer.setSaturation(progress);   break;  case ToneLayer.FLAG_LUM:   mToneLayer.setLum(progress);   break;  case ToneLayer.FLAG_HUE:   mToneLayer.setHue(progress);   break;  }    mImageView.setImageBitmap(mToneLayer.handleImage(mBitmap, flag)); } @Override public void onStartTrackingTouch(SeekBar seekBar) {   } @Override public void onStopTrackingTouch(SeekBar seekBar) {   }}


三、布局文件:

<?xml version="1.0" encoding="utf-8"?><ScrollView xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    >     <LinearLayout      android:layout_width="match_parent"     android:layout_height="match_parent"     android:orientation="vertical" >      <ImageView         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:layout_weight="1"         android:id="@+id/img_view"         android:layout_gravity="center"         />     <LinearLayout         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:id="@+id/tone_view"         /> </LinearLayout></ScrollView>


 

           

给我老师的人工智能教程打call!http://blog.csdn.net/jiangjunshow

这里写图片描述

猜你喜欢

转载自blog.csdn.net/sdfsdfytre/article/details/83986826