我需要为我正在制作的游戏进行角色精灵的调色板交换,所以如果不止一个玩家选择相同的角色,它们将采用不同的颜色。我已将所有精灵存储在BufferedImages中,并希望动态更改调色板。
例如,我想将任何红色到蓝色的像素,任何黑色到橙色的像素以及任何黄色到粉红色的像素都更改。我需要换掉25种颜色。
我已经完成了一些研究,看起来我将不得不创建某种ColorModel并从该模型创建一个新的BufferedImage?我不知道如何创建一个ColorModel,所以如果有一个教程,那将非常有用。
谢谢!
答案 0 :(得分:1)
如果速度无关紧要,我会选择最愚蠢的解决方案:只需手动交换颜色即可。
您可以使用BufferedImage.getRGB(...)获取所有像素值。然后检查颜色是否在您的列表中并相应地替换它。稍后您可以使用setRGB保存新颜色。
这是一个例子:
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import javax.imageio.ImageIO;
public class Equ{
public static void main(String[] args) throws IOException {
BufferedImage img = new BufferedImage( 20, 20, BufferedImage.TYPE_INT_ARGB );
Graphics2D g = img.createGraphics();
g.setColor( Color.white );
g.fillRect( 0, 0, 20, 20 );
g.setColor( Color.black );
g.fillRect( 5, 5, 10, 10 );
Color[] mapping = new Color[]{
Color.black, Color.white, // replace black with white
Color.white, Color.green // and white with green
};
ImageIO.write( img, "png", new File( "original.png" ) );
swapColors( img, mapping );
ImageIO.write( img, "png", new File( "swapped.png" ) );
}
public static void swapColors( BufferedImage img, Color ... mapping ){
int[] pixels = img.getRGB( 0, 0, img.getWidth(), img.getHeight(), null, 0, img.getWidth() );
HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
for( int i = 0; i < mapping.length/2; i++ ){
map.put( mapping[2*i].getRGB(), mapping[2*i+1].getRGB() );
}
for( int i = 0; i < pixels.length; i++ ){
if( map.containsKey( pixels[i] ) )
pixels[i] = map.get( pixels[i] );
}
img.setRGB( 0, 0, img.getWidth(), img.getHeight(), pixels, 0, img.getWidth() );
}
}
答案 1 :(得分:1)
以下代码通过构建共享原始栅格数据的新BufferedImage来交换调色板。所以它运行得很快,并没有太多的记忆。
static BufferedImage switchPalette(BufferedImage bi,
IndexColorModel icm) {
WritableRaster wr = bi.getRaster();
boolean bAlphaPremultiplied = bi.isAlphaPremultiplied();
return new BufferedImage(icm, wr, bAlphaPremultiplied, new Hashtable());
}