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

来源:互联网 发布:百度贴吧一键签到软件 编辑:程序博客网 时间:2024/04/28 15:36

原图:

处理后:

一、图片处理层:

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 maylian7700@126.com * */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 = 50;private 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(); // 新建paintpaint.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// docbreak;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 maylian7700@126.com * */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>


android技术上如有疑问可以问我,有问必答.

爱品茶的盆友,光顾小店(谢谢,能收藏最好了大笑):

http://lancezone.taobao.com


专注移动开发!继续前行~


0 0
原创粉丝点击