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

Bun*_*num 6 java image-processing

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

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

我已经看过Colorize灰度图像,但我似乎无法用Java表达他的工作.我最终得到的图像到处都是相当明亮的霓虹色.

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

有没有人有一个很好的方法来做到这一点?

编辑:

这是我可能尝试着色的图像: 样本体

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

我已经能够使用LookupOp在某种程度上基于Java中的Colorizing图像工作,但颜色总是看起来单调和黑暗.

这是我输出的一个例子: 样本输出

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

编辑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);
Run Code Online (Sandbox Code Playgroud)

Mig*_*uel 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
Run Code Online (Sandbox Code Playgroud)

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

看来您想要特殊处理较暗的色调,因为您没有对 30 以下的任何颜色进行着色。遵循相同的逻辑,您是否也应该免除对较高值进行着色?这将防止白色和接近白色的颜色被染色。

您不应该将 alpha 值与 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])
    }
}
Run Code Online (Sandbox Code Playgroud)

注意:您必须提供HSL到RGB的转换函数。请参阅我对灰度图像着色的回答以获取源代码的链接。