Java の BufferedImage は getType() を使うことでタイプを知ることが出来ます。
byte型でABGRの順に記録されている場合は、BufferedImage.TYPE_4BYTE_ABGR
int型でARGBが記録されている場合は、BufferedImage.TYPE_INT_ARGB になります。
TYPE_4BYTE_ABGR の画像を、
ColorConvertOp(中ではg.drawImage(image, 0, 0, null);) を利用して変換すると、なぜか色が変わる場合があります。※
PixelGrabber を利用すれば、色は変わらないです。
ですが、直接変換する方法のサンプルを紹介します。
BufferedImage から int型のデータを取得するサンプルにもなると思います。
BufferedImage.TYPE_4BYTE_ABGR の image から
BufferedImage.TYPE_INT_ARGB の newimage へ
int width = image.getWidth(); int height = image.getHeight(); int pixelsize = width * height; BufferedImage newimage = new BufferedImage(width,height,BufferedImage.TYPE_INT_ARGB); int[] pixels = ((DataBufferInt)(newimage.getRaster().getDataBuffer())).getData(); byte[] binary = ((DataBufferByte)(image.getRaster().getDataBuffer())).getData(); int r,g,b,a; for(int i=0,j=0;i<pixelsize;i++) { a = binary[j++]&0xff; b = binary[j++]&0xff; g = binary[j++]&0xff; r = binary[j++]&0xff; pixels[i] = (a<<24)|(r<<16)|(g<<8)|b; }
以上です。
BufferedImage.TYPE_3BYTE_BGR の場合は
b = binary[j++]&0xff; g = binary[j++]&0xff; r = binary[j++]&0xff; pixels[i] =0xff000000|(r<<16)|(g<<8)|b;
BufferedImage.TYPE_CUSTOM で取得した DataBuffer のタイプが TYPE_BYTE の場合も
上記のような感じで変換できるようです。
但し、順番が下記のようになるっぽいです。
BufferedImage.TYPE_CUSTOM かつ getColorModel().hasAlpha() で true の場合は
r = binary[j++]&0xff; g = binary[j++]&0xff; b = binary[j++]&0xff; a = binary[j++]&0xff; pixels[i] = (a<<24)|(r<<16)|(g<<8)|b;
BufferedImage.TYPE_CUSTOM かつ getColorModel().hasAlpha() で false の場合は
r = binary[j++]&0xff; g = binary[j++]&0xff; b = binary[j++]&0xff; pixels[i] = 0xff000000|(r<<16)|(g<<8)|b;
ImageIO.read で読み込んだ時点で、
インデックスカラーとグレースケール以外は、TYPE_INT_ARGB に変換してくれればいいのに。
追記メモ
色が変わると言ったのですが、drawImageの品質を
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_DISABLE);
を使って上げればもしかしたら防げるかもしれない。
コメント
[…] 「BufferedImage」の TYPE_4BYTE_ABGR から TYPE_INT_ARGB にする方法 「BufferedImage」の TYPE_BYTE_GRAY から TYPE_BYTE_INDEXED にする方法 カテゴリー: […]