How can I colorize grayscale images with transparency in Java?

I am creating an avatar generator where the avatar components are from PNG files with transparency. Files such as body_1.png or legs_5.png. The transparency around the parts, but not inside them, but the image is in shades of gray. Parts overlap perfectly, and I can get a grayscale image.

I would like to be able to color these parts dynamically, but so far I have not been very lucky. I tried to convert the pixel data from RGB to HSL and use the original L value of the pixel L, and when supplying a new color value H, but the results are small.

I looked at the grayscale color image , but it seems I can’t say that it speaks Java. As a result, I get an image with pretty bright neon colors.

I would like the transparency to remain when painting the part in shades of gray. The black outlines should be black, and the white areas of the selection should be white (I think).

Does anyone have a good way to do this?

EDIT:

Here is an image I could try: Sample body

Again, I want to maintain image brightness levels in shades of gray (so that the outlines remain dark, gradients are visible, and white spots are white).

I managed to get LookupOp to work based on color images in Java , but colors always look gray and dark.

Here is an example of my output: Sample output

The color used is one (note the difference in brightness): 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 LookupOp to use the following and got a lot of nice 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); 
+6
source share
1 answer

Something like this seems to work for you:

 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 viewing your images, I have a few comments:

It seems you want special attention to be paid to dark tones, since you are not coloring anything below 30. Following the same logic, shouldn't you also paint higher values? This will prevent shades of white and white from appearing in color.

You should not set alpha values ​​with RGB. The alpha value from the original image should always be kept. The algorithm of your lookup table should only affect RGB.

As long as you say that you tried HSL, this is not in the code that you published. You have to make your coloring in HSL and then convert the resulting colors to RGB for your lookup table, as this will preserve the original brightness of the shades of gray. Creating a lookup table might look 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 must provide the HSL to RGB conversion function. Check out my answer to Grayscale Color Image for source code links.

+2
source

Source: https://habr.com/ru/post/898451/


All Articles