2009-10-03 10 views
7

Estoy buscando una clase de carga de imágenes TGA pequeña y gratuita o biblioteca para Java. Idealmente, el resultado es una Imagen Buffered.Cargador Java TGA

Sí, ya he buscado en Google, pero la mayoría de los resultados son obsoletos, o son bibliotecas bastante grandes que contienen muchas otras cosas que no necesito. Estoy buscando algo pequeño y simple que solo lea imágenes TGA.

Gracias!

Respuesta

8

Usamos esta clase copiada de algún proyecto de código abierto para leer archivos TGA. Es realmente viejo. Solo puede manejar archivos Targa con la codificación más básica. Darle una oportunidad.

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

muchas gracias! un primer intento me da una arrayoutofboundsexception en esta línea: \t \t \t \t for (int i = 0; i <= nb; i ++) \t \t \t \t \t pixeles [idx ++] = v; – clamp

+0

@clamp change <= nb to throwaway

+0

El resultado de mi imagen se volteó hacia abajo. ¿algún consejo? – squallbayu

9

Tenía imágenes de targa sin comprimir, así que tuve que modificar el código de ejemplo. Aquí está mi edición se debe apoyar sin comprimir BGR Targa 24 bits y 32 bits 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; 
     } 
} 
+0

Hola, ¿Quién, sigues aquí? gracias por su respuesta, casi solucionó perfectamente mi problema, pero todavía hay una pequeña imperfección, es decir, nunca corregir la dirección del archivo tga. –

+0

Im aquí, ¿su problema es una orientación incorrecta/volteada/duplicada? ¿En la pantalla o guardado en el archivo png? Ejemplo de archivos tga disponible? – Whome

+0

Hola, este es mi problema y alguien me ha ofrecido la respuesta ... Gracias. http://stackoverflow.com/questions/29845136/how-to-get-the-direction-of-tga-file-in-java –

4

He añadido una copia independiente de la biblioteca de Interactivo ImageIO TGA realidad aquí (LGPL):

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


Simplemente agregue el archivo jar a su classpath y regístrese con ImageIO:

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

Gracias por compartirlo!

He realizado algunos cambios para mejorar el rendimiento. Solo estoy descifrando el archivo BGRA 32 Bits, pero puede ayudar a otras personas.

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

Por si acaso alguien está buscando la versión de Android de este (tuve que reemplazar BufferedImage con 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; 
    } 
} 
Cuestiones relacionadas