2011年9月16日金曜日

「BufferedImage」の TYPE_4BYTE_ABGR から TYPE_INT_ARGB にする方法

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 に変換してくれればいいのに。

0 件のコメント:

コメントを投稿