Android: How to change the hue of an image?

I want to change the hue of my background image (PNG) programmatically. How can this be done on Android?

+3
source share
2 answers

A related message has some good ideas, but the mathematical matrix used for ColorFilter can be (a) complex overcrowding and (b) introduce tangible shifts in the resulting colors.

Changing the solution given by janin here - fooobar.com/questions/22585 / ... - I based this version on the Color Blend Mode in Photoshop . It doesn't seem to spoil the image caused by PorterDuff.Mode.Multiply, and works great for tinting shades of unsaturated / artificial black-and-white images without loss of contrast.

/*
 * Going for perceptual intent, rather than strict hue-only change. 
 * This variant based on Photoshop '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);
}
+2
source

I tested the accepted answer, unfortunately, it returns an incorrect 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;
}
+4
source

All Articles