JavaのTGAローダ
-
19-09-2019 - |
質問
私は、Javaのための小型で無料のTGA画像の読み込みクラスまたはライブラリを探しています。 理想的には結果がBufferedImageのです。
はい、私はすでにGoogleで検索しているが、ほとんどの結果が古くなっている、または私が必要といけない他の多くのものが含まれている、非常に大きなライブラリです。私はTGAの画像を読み取る小型でシンプルなものを探しています。
ありがとうございます。
解決
私たちは、TGAファイルを読み取るために、いくつかのオープンソースプロジェクトからコピーされたこのクラスを使用します。それは本当に古いです。それは唯一の最も基本的なエンコーディングでのTargaファイルを処理することができます。それを試してみる。
public class TargaReader
{
public static Image getImage(String fileName) throws IOException
{
File f = new File(fileName);
byte[] buf = new byte[(int)f.length()];
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(f));
bis.read(buf);
bis.close();
return decode(buf);
}
private static int offset;
private static int btoi(byte b)
{
int a = b;
return (a<0?256+a:a);
}
private static int read(byte[] buf)
{
return btoi(buf[offset++]);
}
public static Image decode(byte[] buf) throws IOException
{
offset = 0;
// Reading header
for (int i=0;i<12;i++)
read(buf);
int width = read(buf)+(read(buf)<<8);
int height = read(buf)+(read(buf)<<8);
read(buf);
read(buf);
// Reading data
int n = width*height;
int[] pixels = new int[n];
int idx=0;
while (n>0)
{
int nb = read(buf);
if ((nb&0x80)==0)
{
for (int i=0;i<=nb;i++)
{
int b = read(buf);
int g = read(buf);
int r = read(buf);
pixels[idx++] = 0xff000000 | (r<<16) | (g<<8) | b;
}
}
else
{
nb &= 0x7f;
int b = read(buf);
int g = read(buf);
int r = read(buf);
int v = 0xff000000 | (r<<16) | (g<<8) | b;
for (int i=0;i<=nb;i++)
pixels[idx++] = v;
}
n-=nb+1;
}
BufferedImage bimg = new BufferedImage(width,height,BufferedImage.TYPE_INT_ARGB);
bimg.setRGB(0,0,width,height,pixels,0,width);
return bimg;
}
}
他のヒント
私は非圧縮のTARGAイメージを持っていたので、サンプルコードを微調整する必要がありました。ここに私の編集は、それが圧縮されていないタルガ24ビットBGRと32ビットBGRA
をサポートする必要があります// http://paulbourke.net/dataformats/tga/
// little endian multi-byte integers: "low-order byte,high-order byte"
// 00,04 -> 04,00 -> 1024
class TargaReader {
public static BufferedImage getImage(String fileName) throws IOException {
File f = new File(fileName);
byte[] buf = new byte[(int)f.length()];
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(f));
bis.read(buf);
bis.close();
return decode(buf);
}
private static int offset;
private static int btoi(byte b) {
int a = b;
return (a<0?256+a:a);
}
private static int read(byte[] buf) {
return btoi(buf[offset++]);
}
public static BufferedImage decode(byte[] buf) throws IOException {
offset = 0;
// Reading header bytes
// buf[2]=image type code 0x02=uncompressed BGR or BGRA
// buf[12]+[13]=width
// buf[14]+[15]=height
// buf[16]=image pixel size 0x20=32bit, 0x18=24bit
// buf{17]=Image Descriptor Byte=0x28 (00101000)=32bit/origin upperleft/non-interleaved
for (int i=0;i<12;i++)
read(buf);
int width = read(buf)+(read(buf)<<8); // 00,04=1024
int height = read(buf)+(read(buf)<<8); // 40,02=576
read(buf);
read(buf);
int n = width*height;
int[] pixels = new int[n];
int idx=0;
if (buf[2]==0x02 && buf[16]==0x20) { // uncompressed BGRA
while(n>0) {
int b = read(buf);
int g = read(buf);
int r = read(buf);
int a = read(buf);
int v = (a<<24) | (r<<16) | (g<<8) | b;
pixels[idx++] = v;
n-=1;
}
} else if (buf[2]==0x02 && buf[16]==0x18) { // uncompressed BGR
while(n>0) {
int b = read(buf);
int g = read(buf);
int r = read(buf);
int a = 255; // opaque pixel
int v = (a<<24) | (r<<16) | (g<<8) | b;
pixels[idx++] = v;
n-=1;
}
} else {
// RLE compressed
while (n>0) {
int nb = read(buf); // num of pixels
if ((nb&0x80)==0) { // 0x80=dec 128, bits 10000000
for (int i=0;i<=nb;i++) {
int b = read(buf);
int g = read(buf);
int r = read(buf);
pixels[idx++] = 0xff000000 | (r<<16) | (g<<8) | b;
}
} else {
nb &= 0x7f;
int b = read(buf);
int g = read(buf);
int r = read(buf);
int v = 0xff000000 | (r<<16) | (g<<8) | b;
for (int i=0;i<=nb;i++)
pixels[idx++] = v;
}
n-=nb+1;
}
}
BufferedImage bimg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
bimg.setRGB(0, 0, width,height, pixels, 0,width);
return bimg;
}
}
私はここリアリティInteractiveのImageIOでTGAライブラリ(LGPL)のスタンドアロンコピーを追加しました:
https://github.com/tmyroadctfig/com.realityinteractive.imageio.tga >
ちょうどあなたのクラスパスにjarファイルを追加し、ImageIOにして登録します:
IIORegistry registry = IIORegistry.getDefaultInstance();
registry.registerServiceProvider(
new com.realityinteractive.imageio.tga.TGAImageReaderSpi());
念のために誰もが(私はBufferedImage
でBitmap
を交換しなければならなかった)、このAndroidのバージョンを探しています。
class TargaReader {
public static Bitmap getImage(String fileName) throws IOException {
File f = new File(fileName);
byte[] buf = new byte[(int) f.length()];
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(f));
bis.read(buf);
bis.close();
return decode(buf);
}
private static int offset;
private static int btoi(byte b) {
int a = b;
return (a < 0 ? 256 + a : a);
}
private static int read(byte[] buf) {
return btoi(buf[offset++]);
}
public static Bitmap decode(byte[] buf) throws IOException {
offset = 0;
// Reading header bytes
// buf[2]=image type code 0x02=uncompressed BGR or BGRA
// buf[12]+[13]=width
// buf[14]+[15]=height
// buf[16]=image pixel size 0x20=32bit, 0x18=24bit
// buf{17]=Image Descriptor Byte=0x28 (00101000)=32bit/origin
// upperleft/non-interleaved
for (int i = 0; i < 12; i++)
read(buf);
int width = read(buf) + (read(buf) << 8); // 00,04=1024
int height = read(buf) + (read(buf) << 8); // 40,02=576
read(buf);
read(buf);
int n = width * height;
int[] pixels = new int[n];
int idx = 0;
if (buf[2] == 0x02 && buf[16] == 0x20) { // uncompressed BGRA
while (n > 0) {
int b = read(buf);
int g = read(buf);
int r = read(buf);
int a = read(buf);
int v = (a << 24) | (r << 16) | (g << 8) | b;
pixels[idx++] = v;
n -= 1;
}
} else if (buf[2] == 0x02 && buf[16] == 0x18) { // uncompressed BGR
while (n > 0) {
int b = read(buf);
int g = read(buf);
int r = read(buf);
int a = 255; // opaque pixel
int v = (a << 24) | (r << 16) | (g << 8) | b;
pixels[idx++] = v;
n -= 1;
}
} else {
// RLE compressed
while (n > 0) {
int nb = read(buf); // num of pixels
if ((nb & 0x80) == 0) { // 0x80=dec 128, bits 10000000
for (int i = 0; i <= nb; i++) {
int b = read(buf);
int g = read(buf);
int r = read(buf);
pixels[idx++] = 0xff000000 | (r << 16) | (g << 8) | b;
}
} else {
nb &= 0x7f;
int b = read(buf);
int g = read(buf);
int r = read(buf);
int v = 0xff000000 | (r << 16) | (g << 8) | b;
for (int i = 0; i <= nb; i++)
pixels[idx++] = v;
}
n -= nb + 1;
}
}
Bitmap bimg = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
bimg.setPixels(pixels, 0, width, 0, 0, width, height);
return bimg;
}
}
それを共有してくれてありがとう!
私は、パフォーマンスを向上させるためにいくつかの変更を加えました。私はBGRA 32ビットファイルの復号化をやっているが、それは他の人々を助けることができます。
public static BufferedImage createTGAImage(byte[] buff) throws IOException {
int offset = 0, width = 0, height = 0;
int[] tgaBuffer = null;
if (buff[2] == 0x02) { // BGRA File
offset = 12;
width = (buff[offset + 1] << 8 | buff[offset]);
offset = 14;
height = (buff[offset + 1] << 8 | buff[offset]);
int colorDepth = buff[offset + 2];
if (colorDepth == 0x20) { // 32 bits depth
offset = 18;
int count = width * height;
tgaBuffer = new int[count];
for (int i = 0; i < count; i++) {
byte b = buff[offset++]; //This is for didatic prupose, you can remove it and make inline covert.
byte g = buff[offset++];
byte r = buff[offset++];
byte a = buff[offset++];
tgaBuffer[i] = ((a & 0xFF) << 24 | (r & 0xFF) << 16 | (g & 0xFF)<< 8 | b & 0xFF);
}
}
}
BufferedImage result = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
result.setRGB(0, 0, width, height, tgaBuffer, 0, width);
return result;
}