2009-10-03 5 views
7

Я ищу небольшой и бесплатный класс загрузки или библиотеки изображений TGA для java. В идеале результатом является BufferedImage.Java TGA loader

Да, у меня уже есть googled, но большинство результатов устарело или довольно большие библиотеки, которые содержат много других вещей, которые мне не нужны. Я ищу что-то маленькое и простое, которое читает только изображения TGA.

Спасибо!

ответ

8

Мы используем этот класс, скопированный из некоторого проекта с открытым исходным кодом, для чтения файлов 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; 
     } 
} 
+1

спасибо большое! первая попытка дает мне arrayoutofboundsexception в этой строке: \t \t \t \t для (INT I = 0; я <= пь, я ++) \t \t \t \t \t пикселей [IDX ++] = v; – clamp

+0

@clamp change <= nb to throwaway

+0

Результат моего изображения перевернулся стороной вниз. любой совет? – squallbayu

9

У меня были несжатые изображения Targa, поэтому пришлось подстроить пример кода. Вот мой редактировать она должна поддерживать несжатого тарга 24bit BGR и 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; 
     } 
} 
+0

Привет, Кого вы все еще здесь? спасибо за ваш ответ, он почти полностью решил мою проблему, но есть еще небольшой недостаток, т. е. никогда не правильное направление файла tga. –

+0

Im здесь, ваша проблема является неправильной ориентацией/переворачивается/зеркально? На экране или сохранен в png-файле? Примеры файлов tga? – Whome

+0

Привет, вот моя проблема, и кто-то предложил мне ответ ... Спасибо. http://stackoverflow.com/questions/29845136/how-to-get-the-direction-of-tga-file-in-java –

4

Я добавил отдельную копию реальности 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()); 
1

Спасибо, что поделились ею!

Я внес некоторые изменения, чтобы улучшить производительность. Я только дешифрую файл BGRA 32 Bits, но он может помочь другим людям.

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

Только в случае, если кто-то ищет Android версии этого (мне пришлось заменить BufferedImage с 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; 
    } 
}