在大量搜索后,我没有找到一个完全满足我的需求的答案。然而,我偶然发现了2018年的
this video "Practical Image Processing in Android",它指引我找到了正确的方向:使用
ImageFilterView
类。你可以在这里找到
documentation。
看到他们如何在同一张图片上应用多个过滤器非常有教育意义,并且并不难。它包括使用
ColorMatrix
并通过调用
ColorMatrix.postConcat
方法连接多个其他
ColorMatrix
。最终结果包含了您应用的所有过滤器。
以下是一个示例代码,用于更改图像的亮度和饱和度。
package com.rewieer.imagefilters;
import androidx.appcompat.app.AppCompatActivity;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.SeekBar;
public class MainActivity extends AppCompatActivity {
private ImageView image;
private SeekBar brightnessSeekBar;
private SeekBar saturationSeekBar;
private BitmapDrawable defaultDrawable;
private int brightness = 0;
private int saturation = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
image = findViewById(R.id.mainImage);
defaultDrawable = (BitmapDrawable) image.getDrawable();
brightnessSeekBar = findViewById(R.id.brightnessSeekBar);
saturationSeekBar = findViewById(R.id.saturationSeekBar);
brightnessSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
brightness = progress;
redraw();
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
saturationSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
saturation = progress;
redraw();
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
public void redraw() {
ColorMatrix matrix = new ColorMatrix();
matrix.postConcat(new ColorMatrix(new float[]{
1f, 0, 0, 0, brightness,
0, 1f, 0, 0, brightness,
0, 0, 1f, 0, brightness,
0, 0, 0, 1f, 0
}));
float MS = 1.0F - saturation;
float Rt = 0.2999F * MS;
float Gt = 0.587F * MS;
float Bt = 0.114F * MS;
matrix.postConcat(new ColorMatrix(new float[]{
Rt + saturation, Gt, Bt, 0, 0,
Rt, Gt + saturation, Bt, 0, 0,
Rt, Gt, Bt + saturation, 0, 0,
0, 0, 0, 1f, 0
}));
image.setColorFilter(new ColorMatrixColorFilter(matrix));
}
}
这里最重要的方法是
redraw
。
通过查看
ImageFilterView
源代码,我们也可以通过简单地复制粘贴它们的算法来轻松地为图像应用温暖和对比度。
ImageFilterView
不支持视图绑定。 - Veniamin