Pregunta

Busco una clase de carga de la imagen pequeña y libre TGA o biblioteca de Java. Lo ideal sería que el resultado es un BufferedImage.

Sí, ya he buscado en Google, pero la mayoría de los resultados no están actualizados, o son bastante grandes bibliotecas que contienen una gran cantidad de otras cosas que no necesito. Busco algo pequeño y simple que lee sólo imágenes TGA.

Gracias!

¿Fue útil?

Solución

Utilizamos esta clase copiado de algún proyecto de código abierto para leer archivos TGA. Es muy viejo. Sólo se puede manejar archivos Targa con la mayor parte de codificación 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;
        }
}

Otros consejos

tuve imágenes Targa sin comprimir, por lo que tuvo que modificar 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;
        }
}

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

  

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


Sólo tiene que añadir el archivo de la jarra a la ruta de clases y registrarse con ImageIO:

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

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

Gracias por compartirlo!

He hecho algunos cambios para mejorar el rendimiento. Yo sólo estoy haciendo BGRA 32 Bits archivo descifrar, pero puede ayudar a otros 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;
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top