【问题标题】:Palette Swap an BufferedImage in java调色板在java中交换一个BufferedImage
【发布时间】:2013-02-19 05:33:49
【问题描述】:

我需要为我正在开发的游戏中的角色精灵进行调色板交换,因此如果多个玩家选择同一个角色,它们将具有不同的颜色。我已将所有精灵存储在 BufferedImages 中,并希望动态更改调色板。

例如,我想将任何红色像素更改为蓝色,将任何黑色像素更改为橙色,以及将任何黄色像素更改为粉红色。我需要交换大约 25 种颜色。

我已经进行了一些研究,看起来我将不得不创建某种 ColorModel 并从该模型创建一个新的 BufferedImage?我不知道如何去创建一个 ColorModel,所以如果有这方面的教程,那将非常有帮助。

谢谢!

【问题讨论】:

  • 你是使用抗锯齿还是图像只使用精确的颜色?
  • 准确的颜色:它们是来自 Megaman X 的 16 位精灵
  • 啊,那你可以直接换了..我一会儿发个例子
  • 我的代码对您有帮助吗?

标签: java image-processing image-manipulation


【解决方案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() );  
    }
}

【讨论】:

  • 抱歉来晚了,昨晚我问了这个问题,所以我只是试了一下。效果很好,非常感谢!
【解决方案2】:

以下代码通过构造一个共享原始栅格数据的新 BufferedImage 来交换调色板。所以它运行很快,不会占用太多内存。

static BufferedImage switchPalette(BufferedImage bi,
        IndexColorModel icm) {
    WritableRaster wr = bi.getRaster();
    boolean bAlphaPremultiplied = bi.isAlphaPremultiplied();
    return new BufferedImage(icm, wr, bAlphaPremultiplied, new Hashtable());
}

【讨论】:

  • 在我的情况下,原始缓冲图像具有不同的颜色模型。我似乎抛出了一个异常,说光栅与颜色模型不兼容。关于我可以做些什么来解决这个问题的任何想法?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-25
  • 2013-01-12
  • 2015-02-12
  • 2017-10-05
  • 1970-01-01
  • 2018-06-06
相关资源
最近更新 更多