Forum » Programiranje » [java] branje TGA
[java] branje TGA
DCER ::
Ok, že cel dan se mučim s tem, pa zgleda da sem nesposoben in se več ne bom.
Mogoče pa bo kdo tu vedel, kaj delam narobe oz. ima kako drugo rešitev.
Torej skušam prebrati tga datoteko in jo prikazati. Java sama po sebi tega ne omogoča.
Iskal sem po guglu pa nic pametnega, razen Jimi, ki pa je zgleda iz pradavnine
in mi pravtako ne dela...
Drug nacin, ki sem ga poskusil, je da bi risal posamezne pixle v BufferedImage,
in potem le-to prikazal. Tga je precej enostaven in mene zaenkrat zanima le en tip:
16-bitni Unmapped RGB.
Ima 18 bytov headerja. Od tam pa po dva byta predstavljata en pixel
(ker je little endian, zgleda v bitih to tako: GGGBBBBB ARRRRRGG)
A - alpha, G - green, R - red, B - blue.
Vec o formatu tule: TGA format specification
Tole imam do sedaj:
Tga je pravega formata. Header je dobro prebran (višina, širina- sem preveril.)
Mogoče je problem pri pretvarjanju tga pixla v int? Prvič sem delal z biti
ampak mislim da bi moralo v redu biti. Slika je v redu prebrana, nobeni napak ne dobim,
ampak slika pa se pa ne prikaže pa ni problem pri JLabel, ker sem vmes imel tga16topixel narobe
in se je nek črn tatu narisal. seveda niti podoben pravi sliki, ki poleg vsega še barvasta...
Zdaj pa prazno. Ve kdo kak (lahek) način kako prikazati tga v javi?
Se raje pa bi vedel kaj je narobe z mojo implementacijo
Mogoče pa bo kdo tu vedel, kaj delam narobe oz. ima kako drugo rešitev.
Torej skušam prebrati tga datoteko in jo prikazati. Java sama po sebi tega ne omogoča.
Iskal sem po guglu pa nic pametnega, razen Jimi, ki pa je zgleda iz pradavnine
in mi pravtako ne dela...
Drug nacin, ki sem ga poskusil, je da bi risal posamezne pixle v BufferedImage,
in potem le-to prikazal. Tga je precej enostaven in mene zaenkrat zanima le en tip:
16-bitni Unmapped RGB.
Ima 18 bytov headerja. Od tam pa po dva byta predstavljata en pixel
(ker je little endian, zgleda v bitih to tako: GGGBBBBB ARRRRRGG)
A - alpha, G - green, R - red, B - blue.
Vec o formatu tule: TGA format specification
Tole imam do sedaj:
public static final int TGA16toPixel(byte[] pixel, boolean littleEndian){ byte[] orig = new byte[]{pixel[1], pixel[0]}; int alpha=0; int red=0; int blue=0; int green=0; if (littleEndian){ //blue byte[] b = new byte[4]; pixel = orig; b[0] = pixel[1]; blue = (toInt(b, true) & 31) << 3; //green b = new byte[4]; pixel=orig; b[0]=pixel[0]; green = ((toInt(b, true) & 3) << 6); b[0]=pixel[1]; green = green | ( (toInt(b, true) >>> 2) & 56); //red b=new byte[4]; pixel=orig; b[0] = pixel[0]; red = ((toInt(b, true) & 124) << 1); //alpha b=new byte[4]; pixel=orig; b[0] = pixel[1]; alpha = toInt(b, true) & 128; } int rgba = (alpha << 24) | (red << 16) | (green << 8) | blue; return rgba; } public TGA(InputStream in) throws EOFException, UnsupportedImage, IOException{ //first read fully from inputstream byte[] b = new byte[in.available()]; int kuku = 0; while(in.available()>0){ int len = in.read(b, kuku, in.available()); kuku += len; } //then get/save header identification_Field_Length = b[0]; color_Map_Present = b[1]; image_Type = b[2]; //for (int i=0; i<5; i++) color_Map_Specs[i] = b[3+i]; //x_Origin[0] = b[8]; //x_Origin[1] = b[9]; //y_Origin[0] = b[10]; //y_Origin[1] = b[11]; width[0] = b[12]; width[1] = b[13]; height[0] = b[14]; height[1] = b[15]; pixel_Size = b[16]; //descriptor_Byte = b[17]; //throw exception if format not supported if (identification_Field_Length != 0x00) throw new UnsupportedImage("Identification field should not be present."); if (color_Map_Present != 0x00) throw new UnsupportedImage("Color map should not be present."); if (image_Type != 0x02) throw new UnsupportedImage("Image should be unmapped RGB, but is <unknown>."); if (pixel_Size != 0x10) throw new UnsupportedImage("Image should be 16-bit."); //save data byte[] lul = new byte[2]; //create bufferedimage from rest byte[] nWidth = new byte[4]; byte[] nHeight = new byte[4]; nWidth[0] = width[0]; nWidth[1] = width[1]; nHeight[0] = height[0]; nHeight[1] = height[1]; image = new BufferedImage(Convert.toInt(nWidth, true),Convert.toInt(nHeight, true), BufferedImage.TYPE_INT_ARGB); //System.out.println(Convert.toInt(nWidth, true)); //System.out.println(Convert.toInt(nHeight, true)); for (int w=0; w<Convert.toInt(nWidth, true); w++){ for (int h=0; h<Convert.toInt(nHeight, true); h++){ lul[0] = b[17 + w*(Convert.toInt(nHeight, true))+(2*h)]; lul[1] = b[17 + w*(Convert.toInt(nHeight, true))+(2*h+1)]; image.setRGB(w, h, Convert.TGA16toPixel(lul, true)); } } } public BufferedImage getBufferedImage(){ return image; } } public java.awt.Image getTGAImage(String name) throws FileNotFoundException{ InputStream in = null; java.awt.Image img = null; try{ ZipFile zf = new ZipFile(FILE); ZipEntry ze = zf.getEntry(name); if (ze==null){ zf.close(); throw new FileNotFoundException(name + " not found."); } in = zf.getInputStream(ze); img = (new TGA(in)).getBufferedImage(); zf.close(); }catch (IOException e){ JOptionPane.showMessageDialog(null, "An IO error occured.", "Error in getImage()", JOptionPane.ERROR_MESSAGE); }catch (UnsupportedImage e){ JOptionPane.showMessageDialog(null, "Error reading TGA file (" + name + ") :\n" + e.getMessage(), "Error in getImage()", JOptionPane.ERROR_MESSAGE); return null; } return img; } //sliko hocem prikazati s JLabel Image = new JLabel(new ImageIcon(getTGAImage("test.tga")));
Tga je pravega formata. Header je dobro prebran (višina, širina- sem preveril.)
Mogoče je problem pri pretvarjanju tga pixla v int? Prvič sem delal z biti
ampak mislim da bi moralo v redu biti. Slika je v redu prebrana, nobeni napak ne dobim,
ampak slika pa se pa ne prikaže pa ni problem pri JLabel, ker sem vmes imel tga16topixel narobe
in se je nek črn tatu narisal. seveda niti podoben pravi sliki, ki poleg vsega še barvasta...
Zdaj pa prazno. Ve kdo kak (lahek) način kako prikazati tga v javi?
Se raje pa bi vedel kaj je narobe z mojo implementacijo
- spremenilo: DCER ()
BaToCarx ::
Nisem lih programer.
Samo ko ti prebereš TGA ga potem v spominu konvertiraš v kak Javi prijazen format al ne?
Samo ko ti prebereš TGA ga potem v spominu konvertiraš v kak Javi prijazen format al ne?
DCER ::
Ja, v BufferedImage.
Tule:
image = new BufferedImage(Convert.toInt(nWidth, true),Convert.toInt(nHeight, true), BufferedImage.TYPE_INT_ARGB);
S temle pa določam pixle:
image.setRGB(w, h, Convert.TGA16toPixel(lul, true));
Najbrž je nekaj s pretvorbo pixlov narobe, torej v TGA16toPixel. Sem že parkrat skoz šel, pa nevem... Mogoče mi bo kasneje še kaj kapnilo
Tule:
image = new BufferedImage(Convert.toInt(nWidth, true),Convert.toInt(nHeight, true), BufferedImage.TYPE_INT_ARGB);
S temle pa določam pixle:
image.setRGB(w, h, Convert.TGA16toPixel(lul, true));
Najbrž je nekaj s pretvorbo pixlov narobe, torej v TGA16toPixel. Sem že parkrat skoz šel, pa nevem... Mogoče mi bo kasneje še kaj kapnilo
Quikee ::
Mogoce pa ti more TGA16toPixel vracat v 0000 000A 000R RRRR 000G GGGG 000B BBBB.. trenutno mas A000 0000 RRRR R000 GGGG G000 BBBB B000.. Lahko pa da se motim ker ne vem kak ma java to.
kopernik ::
Tukaj imaš kar nekaj povezav do raznih orodij za delo s slikami, tudi TGA format:
http://www.geocities.com/marcoschmidt.geo/java-image-coding.html
Precej jih je zastonj.
http://www.geocities.com/marcoschmidt.geo/java-image-coding.html
Precej jih je zastonj.
DCER ::
Pri tem se nič ne vidi:
To zgoraj naj bi vrnilo 000000A 000RRRRR 000GGGGG 000BBBBB
Pa se tole imam:
Tale pa naj bi vrnil A0000000 RRRRRR000 GGGGG000 BBBBB000, pri tem se mi zdaj pokaže zeleno violična umetnija.
Kopernik, bil sem na tisti strani, pa sta edino Jimi in ImageLoader obljubljala rešitev, s tem ko ImageLoader stran ni delala. Zdaj pa zgleda da dela. Bom probal zdaj še tega.
/**Converts 16-bit Tga pixel to integer*/ public static final int TGA16toPixel(byte[] pixel, boolean littleEndian){ byte[] orig = new byte[]{pixel[1], pixel[0]}; int alpha=0; int red=0; int blue=0; int green=0; //blue byte[] b = new byte[4]; pixel = orig; b[0] = pixel[1]; blue = (toInt(b, true) & 31); //green b = new byte[4]; pixel=orig; b[0]=pixel[0]; green = ((toInt(b, true) & 3) << 3) & 24; b[0]=pixel[1]; green = (green | ( (toInt(b, true) >> 5) & 7)) & 31; //red b=new byte[4]; pixel=orig; b[0] = pixel[0]; red = ((toInt(b, true) & 124) >> 2) & 31; //alpha b=new byte[4]; pixel=orig; b[0] = pixel[0]; alpha = (toInt(b, true) >> 7)& 1; int rgba = (alpha << 24) | (red << 16) | (green << 8) | blue; return rgba; }
To zgoraj naj bi vrnilo 000000A 000RRRRR 000GGGGG 000BBBBB
Pa se tole imam:
/**Converts 16-bit Tga pixel to integer*/ public static final int TGA16toPixel(byte[] pixel, boolean littleEndian){ byte[] orig = new byte[]{pixel[1], pixel[0]}; int alpha=0; int red=0; int blue=0; int green=0; //blue byte[] b = new byte[4]; pixel = orig; b[0] = pixel[1]; blue = ((toInt(b, true) & 31) << 3) & 248; //green b = new byte[4]; pixel=orig; b[0]=pixel[0]; green = ((toInt(b, true) & 3) << 6) & 192; b[0]=pixel[1]; green = (green | ( (toInt(b, true) >> 2) & 56)) & 248; //red b=new byte[4]; pixel=orig; b[0] = pixel[0]; red = ((toInt(b, true) & 124) << 1) & 248; //alpha b=new byte[4]; pixel=orig; b[0] = pixel[0]; alpha = toInt(b, true) & 128; int rgba = (alpha << 24) | (red << 16) | (green << 8) | blue; return rgba; }
Tale pa naj bi vrnil A0000000 RRRRRR000 GGGGG000 BBBBB000, pri tem se mi zdaj pokaže zeleno violična umetnija.
Kopernik, bil sem na tisti strani, pa sta edino Jimi in ImageLoader obljubljala rešitev, s tem ko ImageLoader stran ni delala. Zdaj pa zgleda da dela. Bom probal zdaj še tega.
Zgodovina sprememb…
- spremenilo: DCER ()
DCER ::
Kopernik... hvala ti! hvala ti! hvala ti! hvala ti! hvala ti! hvala ti! hvala ti! hvala ti! hvala ti! hvala ti! hvala ti!
tale zadnji class je bil prava rešitev. Malo sem ga spremenil, tako da zdaj lahko bere tudi 16 bitne tga (kar sem rabil).
Še enkrat hvala kopernik. Ravno to sem rabil, en preprost class, ki ga lahko po potrebi spremenim.
Edit: PS: zdi se mi da sem ga prej pri alpha kanalu lomil. Na koncu sem dobil A0000000, moral pa bi 0000000A.
tale zadnji class je bil prava rešitev. Malo sem ga spremenil, tako da zdaj lahko bere tudi 16 bitne tga (kar sem rabil).
/* --- read the pixel data --- Prej: */ for (int i = (height - 1); i >= 0; i--) { srcLine = i * width; for (int j = 0; j < width; j++) { blue = bis.read() & 0xFF; green = bis.read() & 0xFF; red = bis.read() & 0xFF; if (pixelDepth == 32) { alpha = bis.read() & 0xFF; pixels[srcLine + j] = alpha << 24 | red << 16 | green << 8 | blue; } else { pixels[srcLine + j] = red << 16 | green << 8 | blue; } } } /* --- read the pixel data --- Zdaj: */ for (int i = (height - 1); i >= 0; i--) { srcLine = i * width; for (int j = 0; j < width; j++) { if (pixelDepth == 32) { blue = bis.read() & 0xFF; green = bis.read() & 0xFF; red = bis.read() & 0xFF; alpha = bis.read() & 0xFF; pixels[srcLine + j] = alpha << 24 | red << 16 | green << 8 | blue; } else if (pixelDepth == 24){ pixels[srcLine + j] = red << 16 | green << 8 | blue; } else if (pixelDepth == 16) { int second = bis.read() & 0xFF; int first = bis.read() & 0xFF; blue = (second << 3) & 0xFF; green = (((first << 6) & 0xC0) | ((second >>> 2) & 0x38)) & 0xFF; red = ((first << 1) & 0xF8) & 0xFF; alpha = ((first >>> 7) & 0x01) & 0xFF; pixels[srcLine + j] = alpha << 24 | red << 16 | green << 8 | blue; } } }
Še enkrat hvala kopernik. Ravno to sem rabil, en preprost class, ki ga lahko po potrebi spremenim.
Edit: PS: zdi se mi da sem ga prej pri alpha kanalu lomil. Na koncu sem dobil A0000000, moral pa bi 0000000A.
Zgodovina sprememb…
- spremenilo: DCER ()
Vredno ogleda ...
Tema | Ogledi | Zadnje sporočilo | |
---|---|---|---|
Tema | Ogledi | Zadnje sporočilo | |
» | Začetki programiranjaOddelek: Pomoč in nasveti | 3518 (2566) | FTad |
» | [Android] SplošnoOddelek: Programiranje | 2004 (1134) | piki12 |
» | Program zadelanje programčkovOddelek: Pomoč in nasveti | 1565 (1157) | boogie_xlr |
» | [C#] int v byte[] in nazajOddelek: Programiranje | 1801 (1573) | BlueRunner |
» | branje byte[] iz MS access-ove bazeOddelek: Programiranje | 1938 (1848) | BHawk |