Java TGA loader

匿名 (未验证) 提交于 2019-12-03 02:56:01

问题:

I am looking for a small and free TGA image loading class or library for java. Ideally the result is a BufferedImage.

Yes, I have already googled, but most results are outdated, or are quite big libraries that contain a lot of other stuff i dont need. I am looking for something small and simple that reads just TGA images.

Thanks!

回答1:

We use this class copied from some open source project to read TGA files. It's really old. It can only handle Targa files with most basic encoding. Give it a try.

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;         } } 


回答2:

I had uncompressed targa images, so had to tweak example code. Here is my edit it should support uncompressed targa 24bit BGR and 32bit 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;         } } 


回答3:

I've added a standalone copy of Reality Interactive's ImageIO TGA library here (LGPL):

https://github.com/tmyroadctfig/com.realityinteractive.imageio.tga


Just add the the jar file to your classpath and register with ImageIO:

IIORegistry registry = IIORegistry.getDefaultInstance(); registry.registerServiceProvider(     new com.realityinteractive.imageio.tga.TGAImageReaderSpi()); 


回答4:

Just in case anyone is looking for the Android version of this (I had to replace BufferedImage with Bitmap).

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;     } } 


回答5:

Thanks for sharing it!

I've made some changes to improve performance. I'm only doing BGRA 32 Bits file decrypt, but it can help others people.

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; } 


文章来源: Java TGA loader
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!