在Java中使用透明度着色灰度图像的适当方法是什么?

时间:2011-10-01 17:20:29

标签: java image-processing

我正在创建一个头像生成器,其中头像组件来自具有透明度的PNG文件。这些文件类似于body_1.png或legs_5.png。透明度在部件周围,但不在其中,图像都是灰度。部件分层很好,我可以获得灰度化身。

我希望能够动态地为这些部件着色,但到目前为止,我没有好运。我已经尝试将像素数据从RGB转换为HSL并使用原始像素的L值,同时提供新颜色的H值,但结果不是很好。

我看过Colorize grayscale image,但我似乎无法用Java说出他所说的作品。我最终得到的图像到处都是相当明亮的霓虹色。

我想要的是保持透明度,同时着色灰度部分。黑色轮廓应该仍然是黑色,白色高光区域应该仍然是白色(我认为)。

有没有人有这么好的方法呢?

编辑:

这是我可能尝试着色的图像:Sample Body

同样,我想保持灰度图像的亮度级别(因此轮廓保持黑暗,渐变可见,白色斑块为白色)。

我已经能够根据Colorizing images in Java使LookupOp工作,但颜色总是看起来单调和黑暗。

以下是我的输出示例:Sample Output

正在使用的颜色是这一个(注意亮度差异):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);

1 个答案:

答案 0 :(得分:2)

看起来对你有用的东西是这样的:

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

编辑:看到你的图片后,我有几条评论:

似乎你想特别对待较暗的色调,因为你没有着色30以下的任何东西。遵循相同的逻辑,你不应该免除颜色更高的值吗?这样可以防止白人和近白人染色。

您不应该将RGB值与RGB一起设置。应始终保留原始图像的Alpha值。您的查找表算法应该只影响RGB。

虽然您说您尝试过HSL,但这不在您发布的代码中。您应该在HSL中进行着色,然后将生成的颜色转换为RGB用于查找表,因为这将保留灰度的原始亮度。您的查找表创建可能是这样的:

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])
    }
}

注意:您必须提供HSL到RGB转换功能。有关源代码的链接,请参阅Colorize grayscale image上的答案。