您的位置:首页 > 移动开发 > Android开发

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

2014-10-22 15:13 369 查看
转自:http://blog.csdn.net/luohai859/article/details/25388441

原图:



处理后:



下面贴代码:

一、图片处理层:

[java] view
plaincopy

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(); // 新建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;

}

}

二、主界面:

[java] view
plaincopy

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) {

}

}

三、布局文件:

[java] view
plaincopy

<?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>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐