3

我目前正在开发一个需要更改 BufferedImage 中某些颜色的应用程序。(例如黑色到红色)

在使用 BufferedImage 类的 setRGB 方法时,我注意到一些奇怪的行为。

除非指定的 RGB 值已经在图像中的某处具有特征,否则 setRGB 将简单地将其设置为完全透明的像素。

显而易见的解决方法是在图像中包含所有所需的颜色,但是任何人都可以向我解释为什么会发生这种情况,或者如何解决它?谢谢。

public Texture replaceColour(final TextureColour TARGET, final TextureColour REPLACEMENT)
{
            /*
             * You needn't worry about this bit, just some checks my program
             * uses to determine if a similar image has already been created.
             */
    final String PATH = loadedTexturesFilenames.get(REFERENCE) + "!replacedColour:" + TARGET.RGB + ":" + REPLACEMENT.RGB;
    final Texture PATH_TEXTURE = getTexture(PATH);
    if (PATH_TEXTURE == null)
    {
                    /*
                     * This is where the color changing happens.
                     * See below for information on the 'Texture' and
                     * 'TextureColour' classes.
                     */
        final BufferedImage IMAGE = cloneImage(BUFFERED_IMAGE);
        for (int x = 0; x != IMAGE.getWidth(); x++)
        {
            for (int y = 0; y != IMAGE.getHeight(); y++)
            {
                if (getColour(x, y) == TARGET)
                {
                    IMAGE.setRGB(x, y, REPLACEMENT.RGB);
                }
            }
        }
        return new Texture(IMAGE, PATH);
    }
    else
    {
        return PATH_TEXTURE;
    }
}

public static BufferedImage cloneImage(final BufferedImage I) 
{
     ColorModel colour = I.getColorModel();
     boolean alpha = colour.isAlphaPremultiplied();
     WritableRaster writableRaster = I.copyData(null);
     return new BufferedImage(colour, writableRaster, alpha, null);
}

关于代码的一些注释:

  • 我的程序使用“纹理”类来“有效地”存储 BufferedImages。
  • 以下方法在 Texture 类中。
  • 'TextureColour' 类在另一个包含颜色的 BufferedImage 上存储使用 getRGB(x, y) 生成的 RGB 值。这样做是为了避免混淆 RGB 值并允许在不更改代码的情况下更改颜色。
  • getColour(x, y) 消息根据 BufferedImage.getRGB(x, y) 给出的结果返回“TextureColour”。
4

2 回答 2

1

我猜图像使用的是索引颜色模型,因此只能绘制图像中已经存在的颜色。尝试使用 TYPE_INT_ARGB 创建克隆图像。就像是:

BufferedImage image = new BufferedImage(I.getWidth(), I.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics g = image.getGraphics();
//draw original image I to the new graphics
g.dispose();
return image;

我希望这可以解决您的问题,如果没有您的图像数据,很难在本地重现它......

于 2012-11-13T17:09:00.977 回答
1

请注意,setRGB 的文档指出“对于具有 IndexColorModel 的图像,选择具有最接近颜色的索引。”

在您的包装类中,您的 BufferedImages 是否有任何方式可能是索引类型?如果是这样,您可能希望在操作之前从现有的类型为 TYPE_INT_ARGB 而不是索引类型创建一个新的 BufferedImage。

于 2012-11-13T17:10:40.830 回答