开发者

What's the appropriate way to colorize a grayscale image with transparency in Java?

开发者 https://www.devze.com 2023-04-10 04:00 出处:网络
I\'m making an avatar generator where the avatar components are from PNG files with transparency. The files are things like body_1.png or legs_5.png. The transparency is around the parts but not withi

I'm making an avatar generator where the avatar components are from PNG files with transparency. The files are things like body_1.png or legs_5.png. The transparency is around the parts but not within them and the images are all grayscale. The parts are layering fine and I can get a grayscale avatar.

I would like to be able to colorize these parts dynamically, but so far I'm not having good luck. I've tried converting the pixel data from RGB to HSL and using the original pixel's L value, while supplying the new color's H value, but the results are not great.

I've looked at Colorize grayscale image but I can't seem to make what he's saying work in Java. I end up with an image that has fairly bright, neon colors everywhere.

What I would like is for transparency to remain, while colorizing the grayscale part. The black outlines should still be black and the white highlight areas should still be white (I think).

Does anyone have a good way to do this?

EDIT:

Here's an image I might be trying to color:

What's the appropriate way to colorize a grayscale image with transparency in Java?

Again, I want to maintain the brightness levels of the grayscale image (so the outlines stay dark, the gradients are visible, and white patches are white).

I've been able to get a LookupOp working somewhat based on Colorizing images in Java but the colors always look drab and dark.

Here's an example of my output:

What's the appropriate way to colorize a grayscale image with transparency in Java?

The color that was being used is this one (note the brightness difference): http://www.color-hex.com/color/b124e7

This is my lookupOp

protected LookupOp createColorizeOp(short R1, short G1, short B1) {
    short[] alpha = new short[256];
short[] red = new short[256];
short[] green = new short[256];
short[] blue = new short[256];

//int Y = 0.3*R + 0.59*G + 0.11*B

    for (short i = 0; i < 30; i++) {
    alpha[i] = i;
        red[i] = i;
        green[i] = i;
        blue[i] = i;
}

for (short i = 30; i < 256; i++) {      
    alpha[i] = i;
    red[i] = (short)Math.round((R1 + i*.3)/2);
        green[i] = (short)Math.round((G1 + i*.59)/2);
        blue[i] = (short)Math.round((B1 + i*.11)/2);

    }


    short[][] data = new short[][] {
            red, green, blue, alpha
    };

    LookupTable lookupTable = new ShortLookupTable(0, data);
    return new LookupOp(lookupTable, null);
}

EDIT 2: I changed my LookupO开发者_开发技巧p to use the following and got much nicer looking colors:

red[i] = (short)((R1)*(float)i/255.0);
green[i] = (short)((G1)*(float)i/255.0);
blue[i] = (short)((B1)*(float)i/255.0);


It seems what will work for you is something like this:

for each pixel
    if pixel is white, black or transparent then leave it alone
    else
        apply desired H and S and make grayscale value the L
        convert new HSL back to RGB

Edit: after seeing your images I have a couple of comments:

It seems you want to special treat darker tones, since you are not colorizing anything below 30. Following the same logic, shouldn't you also exempt from colorizing the higher values? That will prevent the whites and near-whites from getting tinted with color.

You should not be setting the alpha values along with RGB. The alpha value from the original image should always be preserved. Your lookup table algorithm should only affect RGB.

While you say that you tried HSL, that is not in the code that you posted. You should do your colorizing in HSL, then convert the resulting colors to RGB for your lookup table as that will preserve the original brightness of the grayscale. Your lookup table creation could be something like this:

short H = ??; // your favorite hue
short S = ??; // your favorite saturation
for (short i = 0; i < 256; i++) {
    if (i < 30 || i > 226) {
        red[i] = green[i] = blue[i] = i; // don't do alpha here
    }
    else {
        HSL_to_RGB(H, S, i, red[i], green[i], blue[i])
    }
}

Note: you have to provide the HSL to RGB conversion function. See my answer on Colorize grayscale image for links to source code.

0

精彩评论

暂无评论...
验证码 换一张
取 消