Java Android保留一个位图作为更改色调、对比度、饱和度等的源
我正在android应用程序中开发一个功能,用户可以使用SeekBar修改位图的饱和度、色调、对比度等。我为每个处理编写了不同的方法。这可以单独工作,但如果我更改位图的色调,并且在调用任何其他方法(例如饱和度)之前,我希望使用应用的色调进度等保留位图。如果进度设置为默认值,用户应该能够看到原始位图 比如说,, 如果我将位图的色调值更改为200。现在,如果我想编辑饱和度的新位图的饱和度应该与应用色调。如果我将饱和度和色调进度重置为默认值,那么用户应该能够看到原始位图颜色 我尝试了许多方法来实现这种行为,例如在每次方法调用之前复制像素,但都没有帮助。目前,对于每种位图处理类型,我只是在用户单击时将修改后的位图的像素复制到原始位图,但如果我重置所有值,则不会将位图更改为原始颜色。请看我的密码 我希望这将有助于理解这个问题Java Android保留一个位图作为更改色调、对比度、饱和度等的源,java,android,android-studio,image-processing,android-bitmap,Java,Android,Android Studio,Image Processing,Android Bitmap,我正在android应用程序中开发一个功能,用户可以使用SeekBar修改位图的饱和度、色调、对比度等。我为每个处理编写了不同的方法。这可以单独工作,但如果我更改位图的色调,并且在调用任何其他方法(例如饱和度)之前,我希望使用应用的色调进度等保留位图。如果进度设置为默认值,用户应该能够看到原始位图 比如说,, 如果我将位图的色调值更改为200。现在,如果我想编辑饱和度的新位图的饱和度应该与应用色调。如果我将饱和度和色调进度重置为默认值,那么用户应该能够看到原始位图颜色 我尝试了许多方法来实现这种
private Bitmap wallpaper, modifiedWallpaper;
private ImageView imageView;
private ImageButton contrast;
private ImageButton hue;
private ImageButton saturation;
private float contrastProgress;
private float hueProgress;
private float satProgress;
private boolean isBlur, isBright, isContrast;
private boolean isHue, isSaturation, isRGB;
private TextView currentMode;
private SeekBar seekBar;
private Paint paint;
private Canvas canvas;
private CardView editor;
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_customize_wallpaper, container, false);
imageView = view.findViewById(R.id.wallpaper);
rgbContainer = view.findViewById(R.id.rgb);
close = view.findViewById(R.id.close);
currentMode = view.findViewById(R.id.current_mode);
seekBar = view.findViewById(R.id.seekBar);
seekBar.setOnSeekBarChangeListener(seekBarChangeListener);
contrast = view.findViewById(R.id.contrast);
hue = view.findViewById(R.id.hue);
saturation = view.findViewById(R.id.saturation);
contrast.setOnClickListener(this);
hue.setOnClickListener(this);
saturation.setOnClickListener(this);
satProgress = 256f;
loadWallpaper(final String wallpaperUrl);
return view;
}
private void loadWallpaper(final String wallpaperUrl) {
Picasso.get().load(Constants.DOMAIN + wallpaperUrl).into(new Target() {
@Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
wallpaper = bitmap; //original loaded
modifiedWallpaper = wallpaper.copy(Bitmap.Config.ARGB_8888, true);
imageView.setImageBitmap(wallpaper);
}
@Override
public void onBitmapFailed(Exception e, Drawable errorDrawable) {
}
@Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
});
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.contrast : {
wallpaper = modifiedWallpaper.copy(Bitmap.Config.ARGB_8888, true);
isBlur = false;
isBright = false;
isContrast = true;
isHue = false;
isSaturation = false;
isRGB = false;
seekBar.setVisibility(View.VISIBLE);
rgbContainer.setVisibility(View.GONE);
changeIconTint();
seekBar.setOnSeekBarChangeListener(null);
seekBar.setMax(90);
seekBar.setProgress((int) contrastProgress);
seekBar.setOnSeekBarChangeListener(seekBarChangeListener);
currentMode.setText("Contrast");
break;
}
case R.id.hue : {
wallpaper = modifiedWallpaper.copy(Bitmap.Config.ARGB_8888, true);
isBlur = false;
isBright = false;
isContrast = false;
isHue = true;
isSaturation = false;
isRGB = false;
seekBar.setVisibility(View.VISIBLE);
rgbContainer.setVisibility(View.GONE);
changeIconTint();
seekBar.setOnSeekBarChangeListener(null);
seekBar.setMax(180);
seekBar.setProgress((int) hueProgress);
seekBar.setOnSeekBarChangeListener(seekBarChangeListener);
currentMode.setText("Hue");
break;
}
case R.id.saturation : {
wallpaper = modifiedWallpaper.copy(Bitmap.Config.ARGB_8888, true);
isBlur = false;
isBright = false;
isContrast = false;
isHue = false;
isSaturation = true;
isRGB = false;
seekBar.setVisibility(View.VISIBLE);
rgbContainer.setVisibility(View.GONE);
changeIconTint();
seekBar.setOnSeekBarChangeListener(null);
seekBar.setMax(512);
seekBar.setProgress((int) satProgress);
seekBar.setOnSeekBarChangeListener(seekBarChangeListener);
currentMode.setText("Saturation");
break;
}
}
}
private void changeContrast(float contrastProgress) {
float cb = this.contrastProgress == 0 ? 0 : -(this.contrastProgress / 1.8f) * 5;
ColorMatrix cm = new ColorMatrix(new float[]
{
contrastProgress, 0, 0, 0, cb,
0, contrastProgress, 0, 0, cb,
0, 0, contrastProgress, 0, cb,
0, 0, 0, contrastProgress, 0
});
paint = new Paint();
paint.setColorFilter(new ColorMatrixColorFilter(cm));
modifiedWallpaper = wallpaper.copy(Bitmap.Config.ARGB_8888, true);
canvas = new Canvas(modifiedWallpaper);
canvas.drawBitmap(modifiedWallpaper, 0, 0, paint);
imageView.setImageBitmap(modifiedWallpaper);
}
private void changeHue() {
ColorMatrix cm = new ColorMatrix();
float hueProgress = cleanValue() / 90f * (float) Math.PI;
if (hueProgress == 0){
return;
}
float cosVal = (float) Math.cos(hueProgress);
float sinVal = (float) Math.sin(hueProgress);
float lumR = 0.213f;
float lumG = 0.715f;
float lumB = 0.072f;
float[] mat = new float[]
{//logic };
cm.postConcat(new ColorMatrix(mat));
paint = new Paint();
paint.setColorFilter(new ColorMatrixColorFilter(cm));
modifiedWallpaper = wallpaper.copy(Bitmap.Config.ARGB_8888, true);
canvas = new Canvas(modifiedWallpaper);
canvas.drawBitmap(modifiedWallpaper, 0, 0, paint);
imageView.setImageBitmap(modifiedWallpaper);
}
private void changeSaturation() {
ColorMatrix colorMatrix = new ColorMatrix();
colorMatrix.setSaturation(satProgress / 256);
paint = new Paint();
paint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
modifiedWallpaper = wallpaper.copy(Bitmap.Config.ARGB_8888, true);
canvas = new Canvas(modifiedWallpaper);
canvas.drawBitmap(modifiedWallpaper, 0, 0, paint);
imageView.setImageBitmap(modifiedWallpaper);
}
private SeekBar.OnSeekBarChangeListener seekBarChangeListener = new SeekBar.OnSeekBarChangeListener()
{
@Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
if (isContrast) {
contrastProgress = seekBar.getProgress();
Log.d("Contrast", "" + (int) contrastProgress);
changeContrast((float) (seekBar.getProgress() + 10) / 10);
return;
}
if (isHue) {
hueProgress = seekBar.getProgress();
Log.d("Hue", "" + (int) hueProgress);
changeHue();
return;
}
if (isSaturation) {
satProgress = seekBar.getProgress();
Log.d("Saturation", "" + (int) satProgress);
changeSaturation();
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
};
应用筛选器时未保存状态。您可以使用新建颜色矩阵和新建位图创建一个新建绘制。这就是为什么一个过滤器会覆盖上一个过滤器 有几种方法可以解决这个问题。我认为最好的第一步是将“过滤”与“绘图”功能分开。示例:
changestation()
在您的代码中,不仅会更改饱和度,还会将其绘制到屏幕上。
我是这样做的:
@Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
if (isContrast) contrast = (float) (seekBar.getProgress() + 10) / 10
if (isHue) hue = seekBar.getProgress();
if (isSaturation) saturation = seekBar.getProgress();
ColorMatrix matrix = calculateColorMatrix(contrast, hue, saturation);
drawBitmap(matrix);
}
private void drawBitmap(ColorMatrix colorMatrix) {
Paint paint = new Paint();
paint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
modifiedWallpaper = wallpaper.copy(Bitmap.Config.ARGB_8888, true);
canvas = new Canvas(modifiedWallpaper);
canvas.drawBitmap(modifiedWallpaper, 0, 0, paint);
imageView.setImageBitmap(modifiedWallpaper);
}
private ColorMatrix calculateColorMatrix(float contrast, hue, saturation) {
ColorMatrix colorMatrix = new ColorMatrix();
// saturation
colorMatrix.setSaturation(satProgress / 256);
// hue
float cosVal = (float) Math.cos(hueProgress);
float sinVal = (float) Math.sin(hueProgress);
float lumR = 0.213f;
// logic...
colorMatrix.postConcat(new ColorMatrix(mat));
//contrast
// logic...
colorMatrix.postConcat(new ColorMatrix(new float[]
{
contrastProgress, 0, 0, 0, cb,
0, contrastProgress, 0, 0, cb,
0, 0, contrastProgress, 0, cb,
0, 0, 0, contrastProgress, 0
}));
return colorMatrix;
}
这只是一种方法。可能是最简单的一个。如果不希望每次滑块移动时都创建所有过滤器,则可以为每个过滤器保留三个不同的矩阵
,每次只修改其中一个
ColorMatrix色调=新的ColorMatrix();
ColorMatrix sat=新ColorMatrix();
ColorMatrix con=新的ColorMatrix();
@凌驾
public void onProgressChanged(SeekBar SeekBar、int i、boolean b){
如果(isContrast){
con=//创建对比度矩阵的逻辑
}
如果(isHue){
色调//创建色调矩阵的逻辑
}
if(饱和){
//...
饱和状态(…)
}
颜色矩阵=色调。后颜色(sat)。后颜色(con);
绘制位图(矩阵);
}
我还没有亲自测试过这段代码,您可能需要做一些更改,但我希望这会让您走上正确的方向 谢谢。这帮了大忙。我将实现您的逻辑,并将返回给您。我尝试了您的逻辑,它按预期工作。实际上我不知道.postConcat()方法。非常感谢您的指导和帮助。