原图:
处理后:
下面贴代码:
一、图片处理层:
- 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;
- }
- }
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;
}
}
二、主界面:
- 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) {
- }
- }
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>
<?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>