Javaで画像(PNG/GIF)の各ピクセルごとのパレット番号を取得する方法

BufferedImage image = ImageIO.read(new File("1.gif"));
// 「色」の情報を表すクラス
//パレット形式の場合は ColorModelが IndexColorModelのインスタンスになる
ColorModel model = image.getColorModel();
if(model instanceof IndexColorModel) {
IndexColorModel icm = (IndexColorModel)model;
// パレットの大きさ。未使用の部分があっても、常に256になってしまう…
System.out.println(icm.getMapSize());
// パレットのデータ。RGBAがintにパックされる。
int[] rgb = new int[icm.getMapSize()];
icm.getRGBs(rgb);
for(int i=0;i<rgb.length;i++) {
Color c = new Color(rgb[i]);
System.out.printf("%d,%d,%d,%d\n",c.getRed(),c.getGreen(),c.getBlue(),c.getAlpha());
}
int minx = image.getMinX();
int miny = image.getMinY();
int width = image.getWidth();
int height = image.getHeight();
// 「点」の情報を表すクラス
Raster raster = image.getRaster();
// バンド幅。RGBなら3、RGBAなら4になる。
// IndexColorModelの場合は常に1になる(はず)。
int band = raster.getNumBands();
if(band != 1) {
throw new RuntimeException("unexpected bands");
}
// 実際のピクセルごとのデータ。パレットの何番に該当するかが入っている
// 要素数はwidth*height
// (フルカラーの場合はRGB(A)の数値が入っていて、要素数はbands*width*height)
int[] buf = raster.getPixels(minx, miny, width, height, (int[])null);
for(int y=0;y<height;y++) {
for(int x=0;x<width;x++){
System.out.printf("%02d",buf[x+y*width]);
System.out.print(",");
}
System.out.println("");
}
}




最初のパレットかフルカラーかどうかの判定はif(image.getType() == BufferedImage.TYPE_BYTE_INDEXED) (=13)でも可能。
(ちなみに、JPEGの場合はBufferedImage.TYPE_3BYTE_BGR(=5)、フルカラーPNGの場合、BufferedImage.TYPE_CUSTOM (=0) だった。アルファがあったりするとまた変わるらしい)