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

コードに関する注意事項:

  • 「Texture」クラスは、私のプログラムで BufferedImages を「効率的に」格納するために使用されます。
  • 次のメソッドは Texture クラス内にあります。
  • 「TextureColour」クラスは、色を含む別の BufferedImage で getRGB(x, y) を使用して生成された RGB 値を格納します。この方法は、RGB 値の混乱を避け、コードを変更せずに色を変更できるようにするために行われます。
  • getColour(x, y) メッセージは、BufferedImage.getRGB(x, y) によって与えられた結果に従って「TextureColour」を返します。
4

2 に答える 2

1

setRGBのドキュメントには、「IndexColorModelのある画像の場合、最も近い色のインデックスが選択される」と記載されていることに注意してください。

ラッパークラスで、BufferedImagesがインデックス付きタイプになる方法はありますか?その場合は、操作する前に、インデックス付きタイプではなく、タイプTYPE_INT_ARGBの既存のBufferedImageから新しいBufferedImageを作成することをお勧めします。

于 2012-11-13T17:10:40.830 に答える
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 に答える