我需要将BufferedImage转换为BufferedImage索引类型,以提取颜色数据和256色调色板的索引。我认为我正在做正确的BufferedImage到索引模式的转换,然后用下一个代码提取颜色索引:
BufferedImage paletteBufferedImage=new BufferedImage(textureInfoSubFile.getWidth(), textureInfoSubFile.getHeight(),BufferedImage.TYPE_BYTE_INDEXED);
paletteBufferedImage.getGraphics().drawImage(originalBufferedImage, 0, 0, null);
// puts the image pixeldata into the ByteBuffer
byte[] pixels = ((DataBufferByte) paletteBufferedImage.getRaster().getDataBuffer()).getData();
我现在的问题是,我需要知道每个颜色索引(调色板)的ARGB值将它们放入一个数组。我一直在阅读关于ColorModel和ColorSpace,但我没有找到一些方法来做我需要的。
我认为你的代码是好的(除了你不把任何数据"放入"任何东西,你只是引用数据缓冲区的后备数组,这意味着pixels
的变化将反映到paletteBufferedImage
,反之亦然)。
获取pixels
中索引的ARGB值:
IndexColorModel indexedCM = (IndexColorModel) paletteBufferedImage.getColorModel(); // cast is safe for TYPE_BYTE_INDEXED
int[] palette = new int[indexedCM.getMapSize()]; // Allocate array
indexedCM.getRGBs(palette); // Copy palette to array (ARGB values)
更多信息,请参见IndexColorModel类文档
最后我用下面的代码解决了这个问题:
public static BufferedImage rgbaToIndexedBufferedImage(BufferedImage sourceBufferedImage) {
// With this constructor, we create an indexed buffered image with the same dimension and with a default 256 color model
BufferedImage indexedImage = new BufferedImage(sourceBufferedImage.getWidth(), sourceBufferedImage.getHeight(), BufferedImage.TYPE_BYTE_INDEXED);
ColorModel cm = indexedImage.getColorModel();
IndexColorModel icm = (IndexColorModel) cm;
int size = icm.getMapSize();
byte[] reds = new byte[size];
byte[] greens = new byte[size];
byte[] blues = new byte[size];
icm.getReds(reds);
icm.getGreens(greens);
icm.getBlues(blues);
WritableRaster raster = indexedImage.getRaster();
int pixel = raster.getSample(0, 0, 0);
IndexColorModel icm2 = new IndexColorModel(8, size, reds, greens, blues, pixel);
indexedImage = new BufferedImage(icm2, raster, sourceBufferedImage.isAlphaPremultiplied(), null);
indexedImage.getGraphics().drawImage(sourceBufferedImage, 0, 0, null);
return indexedImage;
}