在 Java 中对具有透明度的灰度图像进行着色的正确方法是什么?
我正在制作一个头像生成器,其中头像组件来自具有透明度的 PNG 文件。这些文件类似于 body_1.png 或 Legs_5.png。透明度位于零件周围,但不位于零件内部,并且图像都是灰度的。这些部件分层良好,我可以获得灰度头像。
我希望能够动态地为这些部分着色,但到目前为止我运气不佳。我尝试将像素数据从 RGB 转换为 HSL 并使用原始像素的 L 值,同时提供新颜色的 H 值,但结果并不好。
我看过对灰度图像进行着色,但我似乎无法使他所说的在Java中起作用。我最终得到了一张到处都有相当明亮的霓虹色的图像。
我想要的是保持透明度,同时对灰度部分进行着色。黑色轮廓应该仍然是黑色,白色高光区域应该仍然是白色(我认为)。
有没有人有一个好方法来做到这一点?
编辑:
这是我可能尝试着色的图像:
再次,我想保持灰度的亮度级别图像(因此轮廓保持黑色,渐变可见,并且白色斑块为白色)。
我已经能够让 LookupOp 在某种程度上基于 在 Java 中对图像进行着色 但颜色总是显得单调和黑暗。
这是我的输出示例:
使用的颜色是这个(注意亮度差异): < a href="http://www.color-hex.com/color/b124e7" rel="nofollow noreferrer">http://www.color-hex.com/color/b124e7
这是我的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);
}
编辑 2:我更改了 LookupOp 以使用以下内容,并获得了更好看的颜色:
red[i] = (short)((R1)*(float)i/255.0);
green[i] = (short)((G1)*(float)i/255.0);
blue[i] = (short)((B1)*(float)i/255.0);
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:
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:
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 LookupOp 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);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
看来对你有用的是这样的:
编辑:看到你的图像后,我有一些评论:
看来你想特殊处理较暗的色调,因为你没有对低于 30 的任何颜色进行着色遵循相同的逻辑,您是否也应该免除对较高值进行着色?这将防止白色和接近白色的颜色被染色。
您不应该将 alpha 值与 RGB 一起设置。应始终保留原始图像的 alpha 值。您的查找表算法应该只影响 RGB。
虽然您说您尝试过 HSL,但这并不在您发布的代码中。您应该在 HSL 中进行着色,然后将结果颜色转换为 RGB 以用于查找表,因为这将保留灰度的原始亮度。您的查找表创建可能如下所示:
注意:您必须提供 HSL 到 RGB 转换函数。请参阅我对对灰度图像进行着色的回答,获取源代码的链接。
It seems what will work for you is something like this:
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:
Note: you have to provide the HSL to RGB conversion function. See my answer on Colorize grayscale image for links to source code.