문제

저는 Java용 소형 무료 TGA 이미지 로딩 클래스나 라이브러리를 찾고 있습니다.이상적으로 결과는 BufferedImage입니다.

예, 이미 검색했지만 대부분의 결과는 오래되었거나 필요하지 않은 다른 항목이 많이 포함된 꽤 큰 라이브러리입니다.저는 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 이미지가 있었으므로 예제 코드를 조정해야했습니다. 내 편집은 압축되지 않은 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;
        }
}

Reality Interactive의 Imageio TGA Library (LGPL)의 독립형 사본을 추가했습니다.

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


ClassPath에 JAR 파일을 추가하고 ImageIO에 등록하기 만하면됩니다.

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

누구나이 버전의 안드로이드 버전을 찾고있는 경우를 대비하여 (교체해야했습니다. 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;
    }
}

공유해 주셔서 감사합니다!

성능을 향상시키기 위해 몇 가지 변경을했습니다. 나는 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;
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top