Java TGA-Loader
-
19-09-2019 - |
Frage
Ich bin für eine kleine und kostenlose TGA Bildlade Klasse oder Bibliothek für Java. Im Idealfall ist das Ergebnis ein BufferedImage.
Ja, ich habe schon gegoogelt, aber die meisten Ergebnisse sind veraltet, oder sind recht groß Bibliotheken, die eine Menge anderer Sachen enthalten i dont need. Ich bin auf der Suche nach etwas klein und einfach, die nur TGA Bilder lesen.
Danke!
Lösung
Wir werden diese Klasse von einem Open-Source-Projekt kopiert verwenden TGA-Dateien zu lesen. Es ist wirklich alt. Es kann nur Targa Dateien mit grundlegender Codierung behandeln. Probieren Sie es aus.
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;
}
}
Andere Tipps
hatte ich unkomprimiert targa Bilder, hatte so zu zwicken Beispielcode. Hier ist meine bearbeiten sollte es unkomprimiert targa unterstützen 24bit BGR und 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;
}
}
Ich habe eine eigenständige Kopie von Reality Interactive ImageIO TGA-Bibliothek hinzugefügt hier (LGPL):
https://github.com/tmyroadctfig/com.realityinteractive.imageio.tga
Fügen Sie einfach die die JAR-Datei auf Ihrem Classpath und registrieren mit ImageIO:
IIORegistry registry = IIORegistry.getDefaultInstance();
registry.registerServiceProvider(
new com.realityinteractive.imageio.tga.TGAImageReaderSpi());
Für den Fall, jemand für die Android-Version dieser Suche (ich hatte BufferedImage
mit Bitmap
ersetzen).
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;
}
}
Vielen Dank für den Austausch it!
Ich habe einige Änderungen zur Verbesserung der Leistung. Ich bin nur BGRA 32 Bits Datei entschlüsseln zu tun, aber es kann andere Menschen helfen.
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;
}