我正在寻找以编程方式更改背景图像 (PNG) 的色调。如何在 Android 上做到这一点?
问问题
8276 次
3 回答
6
I tested the accepted answer, unfortunately it returns a wrong result. I found and modified this code from here which works fine:
// hue-range: [0, 360] -> Default = 0
public static Bitmap hue(Bitmap bitmap, float hue) {
Bitmap newBitmap = bitmap.copy(bitmap.getConfig(), true);
final int width = newBitmap.getWidth();
final int height = newBitmap.getHeight();
float [] hsv = new float[3];
for(int y = 0; y < height; y++){
for(int x = 0; x < width; x++){
int pixel = newBitmap.getPixel(x,y);
Color.colorToHSV(pixel,hsv);
hsv[0] = hue;
newBitmap.setPixel(x,y,Color.HSVToColor(Color.alpha(pixel),hsv));
}
}
bitmap.recycle();
bitmap = null;
return newBitmap;
}
于 2014-09-14T14:08:56.150 回答
2
链接的帖子有一些好主意,但用于 ColorFilter 的矩阵数学可能是 (a) 复杂的过度杀伤,和 (b) 在结果颜色中引入可感知的变化。
在此处修改 janin 给出的解决方案 - https://stackoverflow.com/a/6222023/1303595 - 我将此版本基于Photoshop 的“颜色”混合模式。它似乎避免了由 PorterDuff.Mode.Multiply 引起的图像变暗,并且在不损失太多对比度的情况下非常适用于着色去饱和/人工黑白图像。
/*
* Going for perceptual intent, rather than strict hue-only change.
* This variant based on Photoshop's 'Color' blending mode should look
* better for tinting greyscale images and applying an all-over color
* without tweaking the contrast (much)
* Final color = Target.Hue, Target.Saturation, Source.Luma
* Drawback is that the back-and-forth color conversion introduces some
* error each time.
*/
public void changeHue (Bitmap bitmap, int hue, int width, int height) {
if (bitmap == null) { return; }
if ((hue < 0) || (hue > 360)) { return; }
int size = width * height;
int[] all_pixels = new int [size];
int top = 0;
int left = 0;
int offset = 0;
int stride = width;
bitmap.getPixels (all_pixels, offset, stride, top, left, width, height);
int pixel = 0;
int alpha = 0;
float[] hsv = new float[3];
for (int i=0; i < size; i++) {
pixel = all_pixels [i];
alpha = Color.alpha (pixel);
Color.colorToHSV (pixel, hsv);
// You could specify target color including Saturation for
// more precise results
hsv [0] = hue;
hsv [1] = 1.0f;
all_pixels [i] = Color.HSVToColor (alpha, hsv);
}
bitmap.setPixels (all_pixels, offset, stride, top, left, width, height);
}
于 2012-06-26T05:16:27.373 回答
0
If you wrap your Bitmap in an ImageView
there is a very simple way:
ImageView circle = new ImageView(this);
circle.setImageBitmap(yourBitmap);
circle.setColorFilter(Color.RED);
My guess is this will be faster than modifying each pixel individually.
于 2020-06-17T19:14:01.503 回答