我们的实现的效果是类似photoshop,调节RGB三通道的比重、透明度、色彩饱和度
先回答这个问题,把大象放冰箱需要几步?
给定一个bitmap,调节RGB三通道的比重、透明度、色彩饱和度需要几步?
构建画布
注意:先复制一张跟原图一模一样的bitmap,不能在原图上做修改
构建画笔
注意:构建一个画笔,然后给画笔设置setColorFilter,这里需要传入ColorMatrix(关键就是这个ColorMatrix)
切记,不能使用colorMatrix.setRotate()连续设置各个通道的色调,这样的话,会让最后一个覆盖前面的效果,而是要通过postConcat混合多个ColorMatrix
用构建好的画笔,在构建好的画布上画这个bitmap
代码注释写的很清楚了
package performance.brilliant.com.brilliantperformance.view;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
/**
* 描述当前版本功能
*
* @Project: BrilliantPerformance
* @author: cjx
* @date: 2019-07-18 21:55 星期四
*/
public class ImageHelper {
/**
* @param srcBitmap 要改变的原图,注意不要在这个原图上做修改,要复制一张图出来做修改
* @param hueR 红色调 越大,红色越浓重
* @param hueG 绿色调 越大,绿色越浓重
* @param hueB 蓝色调 越大,蓝色越浓重
* @param saturation 饱和度 颜色丰富程度:0表示黑白效果;越大,颜色越艳丽
* @param lumR 红亮度 明暗程度:0表示红色亮度为黑,越大越白
* @param lumG 绿亮度 明暗程度:0表示绿色亮度为黑,越大越白
* @param lumB 蓝亮度 明暗程度:0表示蓝色亮度为黑,越大越白
* @param lumA 透明度亮度 明暗程度:0表示透明度为黑,越大越白
* @return 变换后的bitmap https://www.jianshu.com/p/9a44d04f39fc
*/
public static Bitmap handlerImageEffect(Bitmap srcBitmap,
float hueR, float hueG, float hueB,
float saturation,
float lumR, float lumG, float lumB, float lumA) {
// **************************** 一、构建画布,新的bitmap画布 ****************************
// 先复制一张跟原图一模一样的bitmap,不能在原图上做修改
Bitmap newBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), Bitmap.Config.ARGB_8888);
// 注意这里是new了一个新的Canvas,把newBitmap与他绑定在一起
Canvas canvas = new Canvas(newBitmap);
// **************************** 二、构建画笔,画笔要设置ColorMatrixColorFilter ****************************
// ColorMatrixColorFilter需要一个ColorMatrix参数
// ColorMatrix可以通过postConcat把各种ColorMatrix进行混合
// ColorMatrix的api支持设置 色调、饱和度、亮度(其实本质上是对4*5颜色矩阵的封装)
// ★★★★★切记,不能使用setRotate连续设置各个通道的色调(如下段注释掉的代码),这样的话,会让最后一个覆盖前面的效果
// mHueMatrix.setRotate(0, mHueValue);
// mHueMatrix.setRotate(1, mHueValue);
// mHueMatrix.setRotate(2, mHueValue);
// ★★★★★★应该按照下面的代码为 设置三个不同的hueMatrix,最后通过postConcat混合效果
//色调 RGB每个颜色通道的值,越大,颜色越浓重
ColorMatrix hueRedMatrix = new ColorMatrix();
hueRedMatrix.setRotate(0, hueR);// axis=0:RED color
ColorMatrix hueGreenMatrix = new ColorMatrix();
hueGreenMatrix.setRotate(1, hueG);// axis=1:GREEN color
ColorMatrix hueBlueMatrix = new ColorMatrix();
hueBlueMatrix.setRotate(2, hueB);// axis=2:BLUE color
//饱和度 颜色丰富程度:0表示黑白效果
ColorMatrix saturationMatrix = new ColorMatrix();
saturationMatrix.setSaturation(saturation);
//亮度 明暗程度:0表示一片漆黑
ColorMatrix lumMatrix = new ColorMatrix();
lumMatrix.setScale(lumR, lumG, lumB, lumA);
// 把所有的Matrix混合起来,构建一个ColorMatrix
ColorMatrix imageMatrix = new ColorMatrix();
imageMatrix.postConcat(hueRedMatrix);
imageMatrix.postConcat(hueGreenMatrix);
imageMatrix.postConcat(hueBlueMatrix);
imageMatrix.postConcat(saturationMatrix);
imageMatrix.postConcat(lumMatrix);
//构建一支画笔
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
// 给画笔设置这个ColorMatrix
paint.setColorFilter(new ColorMatrixColorFilter(imageMatrix));
// **************************** 三、开始作画了, ****************************
// 使用上面混合了ColorMatrix那只笔,
// 在与newBitmap关联的的canvas上作画
// 画什么,画的是原图srcBitmap
canvas.drawBitmap(srcBitmap, 0, 0, paint);
// 返回newBitmap
return newBitmap;
}
}
package performance.brilliant.com.brilliantperformance;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.widget.ImageView;
import android.widget.SeekBar;
import performance.brilliant.com.brilliantperformance.view.ImageHelper;
public class LinearGradientActivity extends AppCompatActivity implements SeekBar.OnSeekBarChangeListener {
private ImageView mImageView;
private SeekBar bar_hueR;
private SeekBar bar_hueG;
private SeekBar bar_hueB;
private SeekBar bar_saturation;
private SeekBar bar_lumR;
private SeekBar bar_lumG;
private SeekBar bar_lumB;
private SeekBar bar_lumA;
private Bitmap mSrc;
private Bitmap mBitmap;
private Handler mHandler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_linear_gradient);
initView();
setListener();
mSrc = BitmapFactory.decodeResource(getResources(), R.drawable.img_hudie);
}
private void setListener() {
bar_hueR.setOnSeekBarChangeListener(this);
bar_hueG.setOnSeekBarChangeListener(this);
bar_hueB.setOnSeekBarChangeListener(this);
bar_saturation.setOnSeekBarChangeListener(this);
bar_lumR.setOnSeekBarChangeListener(this);
bar_lumG.setOnSeekBarChangeListener(this);
bar_lumB.setOnSeekBarChangeListener(this);
bar_lumA.setOnSeekBarChangeListener(this);
}
private void initView() {
mImageView = findViewById(R.id.ivc);
bar_hueR = findViewById(R.id.bar_hueR);
bar_hueG = findViewById(R.id.bar_hueG);
bar_hueB = findViewById(R.id.bar_hueB);
bar_saturation = findViewById(R.id.bar_saturation);
bar_lumR = findViewById(R.id.bar_lumR);
bar_lumG = findViewById(R.id.bar_lumG);
bar_lumB = findViewById(R.id.bar_lumB);
bar_lumA = findViewById(R.id.bar_lumA);
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
changeColor();
}
},300);
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
changeColor();
}
private void changeColor() {
new Thread(new Runnable() {
@Override
public void run() {
mBitmap = ImageHelper.handlerImageEffect
(mSrc, bar_hueR.getProgress(),
bar_hueG.getProgress(),
bar_hueB.getProgress(),
bar_saturation.getProgress(),
bar_lumR.getProgress()*1.0f/100,
bar_lumG.getProgress()*1.0f/100,
bar_lumB.getProgress()*1.0f/100,
bar_lumA.getProgress()*1.0f/100);
mHandler.post(new Runnable() {
@Override
public void run() {
mImageView.setImageBitmap(mBitmap);
}
});
}
}).start();
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
}