【问题标题】:Android: How to change hue of an Image?Android:如何改变图像的色调?
【发布时间】:2012-04-20 23:03:23
【问题描述】:

我希望以编程方式更改背景图像 (PNG) 的色调。如何在 Android 上做到这一点?

【问题讨论】:

标签: android


【解决方案1】:

我测试了接受的答案,不幸的是它返回了错误的结果。我从here 找到并修改了这段代码,效果很好:

// 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;
}

【讨论】:

  • 此代码有效,但速度很慢。有什么优化的想法吗?
【解决方案2】:

链接的帖子有一些好主意,但用于 ColorFilter 的矩阵数学可能 (a) 过于复杂,并且 (b) 会在结果颜色中引入可感知的变化。

在此处修改 janin 给出的解决方案 - https://stackoverflow.com/a/6222023/1303595 - 我基于 Photoshop's 'Color' blend mode 的此版本。它似乎避免了由 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);
}

【讨论】:

    【解决方案3】:

    如果您将位图包装在 ImageView 中,则有一个非常简单的方法:

    ImageView circle = new ImageView(this);
    circle.setImageBitmap(yourBitmap);
    circle.setColorFilter(Color.RED);
    

    我的猜测是这会比单独修改每个像素更快。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-08-29
      • 2020-09-18
      • 1970-01-01
      • 2013-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多