Java BufferedImage:Alpha更改使低alpha区域显示为黑色

时间:2015-10-06 15:33:47

标签: java colors png bufferedimage alpha

我有一种方法可以在Java中更改BufferedImage的alpha值。这是我的代码:

public static void setAlpha(BufferedImage img, byte alpha) {
    alpha %= 0xff;
    for (int cx=0;cx<img.getWidth();cx++) {
        for (int cy=0;cy<img.getHeight();cy++) {
            int color = img.getRGB(cx, cy);
            color &= 0x00ffffff;
            color |= (alpha << 24);
            img.setRGB(cx, cy, color);
        }
    }
}

当我使用此功能时,图像中所有透明的区域变为黑色。为什么呢?

编辑:

非常感谢你的帮助。现在我想通了,问题是什么。这是我的工作职责:

public static void changeAlpha(BufferedImage img, float alphaPercent) {
    for (int cx=0;cx<img.getWidth();cx++) {
        for (int cy=0;cy<img.getHeight();cy++) {
            int color = img.getRGB(cx, cy);
            byte alpha = (byte) (color >> 24);
            alpha = (byte) ((float) (int) (alpha & 0xff) * alphaPercent);
            color &= 0x00ffffff;
            color |= ((alpha & 0xff) << 24);
            img.setRGB(cx, cy, color);
        }
    }
}

1 个答案:

答案 0 :(得分:1)

声明

alpha %= 0xff;

似乎有点奇怪。由于Java byte已签名(并且在[-128 ... 127]范围内),因此永远不会更改alpha(对于字节范围中的任何值,x%255 = x)。

但是,您希望alpha在[0 ... 255]范围内。通常,您使用&运算符执行此操作。但只是更改操作符不会,因为您将值存储在byte中,这会将值再次强制到[-128 ... 127]范围内...

相反,尝试(在你的循环中):

color |= ((alpha & 0xff) << 24);

或者,您可以编写如下内容:

int alphaValue = alpha & 0xff;
for (...) {
    for (...) {
        // Inside the loop:
        color |= (alphaValue << 24);
    }
}

最后,关于透明度的说明。如果之前的像素之前已经100%透明,则该像素中的颜色无关紧要。出于这个原因,它可能被标准化为黑色(所有0 s)以提高效率。可能无法恢复原始颜色。