PNGs mit Java laden und ArrayOutOfBoundsException
-
Hi,
ich hab ein kleines Problem.
Wenn ich versuche ein PNG mit ImageIO.read (URL) zu lesen, bekomme ich folgendes:java.lang.ArrayIndexOutOfBoundsException: 4 at com.sun.imageio.plugins.png.PNGImageReader.parse_PLTE_chunk(Unknown Source) at com.sun.imageio.plugins.png.PNGImageReader.readMetadata(Unknown Source) at com.sun.imageio.plugins.png.PNGImageReader.readImage(Unknown Source) at com.sun.imageio.plugins.png.PNGImageReader.read(Unknown Source) at javax.imageio.ImageIO.read(Unknown Source) at javax.imageio.ImageIO.read(Unknown Source) at web.Web.getPng(Web.java:271)
mein codeausschnitt sieht so aus:
[...] BufferedImage bi = ImageIO.read (new URL (sPngLink)); ImageIO.write (bi, "png", new File ("bild.png")); [...]
Ich benutzte eclipse und windows.
Habt ihr eien idee wie das zu lösen ist?
Danke im voraus (mein erster beitrag in dem forum )
-
Zeig mal die komplette Methode getPng in Deiner Klasse Web.
-
public static void getPng (String sServer, String sPngLink) { BufferedImage bi = ImageIO.read (new URL (sServer + "internal/" + sPngLink)); mageIO.write (bi, "png", new File ("bild.png")); Runtime rtm = Runtime.getRuntime(); try { Process proc = rtm.exec(" \"C:/.....fw.bat\""); proc.waitFor(); } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } }
Das ist es bis jetzt. Ist noch nicht viel, da ich immer Schritt für schritt rangehe.
Das ong soll halt in den ordner gespeichert werden, und dann ruf ich ne batch datei auf, die was mit dem bild macht.
-
@boom: Irgendetwas stimmt da nicht. ImageIO.read kann eine IOException werfen. Du hast die Methode aber weder in einem try-Block, noch definierst Du Deine getPng-Methode so, dass sie auch eine IOException werfen kann.
Dein Code passt also nicht so ganz zu der Laufzeit-Fehlermeldung, die Du am Anfang postest. Er sollte gar nicht erst kompilieren.
EDIT: Aber zeig mal, was in sServer und sPngLink steht.
-
Du hast recht. Das lag daran, dass das ganze in noch ner try catch anweisung lag.
Und ich ging davon aus, dass die das nicht beeinflusst.
(Ich hab viel mit c++ programmiert, deshalb bin ich diese esception-geschichte nicht gewöhnt )public static void getPng (String sServer, String sPngLink) { try { BufferedImage bi = ImageIO.read (new URL (sServer + "internal/" + sPngLink)); ImageIO.write (bi, "png", new File ("bild.png")); } catch (IOException e) { e.printStackTrace(); } Runtime rtm = Runtime.getRuntime(); try { Process proc = rtm.exec(" \"C:/...fw.bat\""); proc.waitFor(); } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } }
Ich hab es jetzt so geändert, dei Meldung bleibt allerdings die gleiche.
In sServer steht höchstwahrscheinlich "http://85.10.193.197/freewar/" und in sPngLink sowas wie "secimg.php?randsec=3500".
-
Hat niemand eine Idee, wie ich das lösen kann?
Hier http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5098176 meinen die, dass es sich dabei um einen bug in java handelt...
Gibt es eine Möglichkeit den bug i-wie zu umgehen?
-
boom schrieb:
Ich hab es jetzt so geändert, dei Meldung bleibt allerdings die gleiche.
In sServer steht höchstwahrscheinlich "http://85.10.193.197/freewar/" und in sPngLink sowas wie "secimg.php?randsec=3500".solte da nicht was von png, anstatt php stehen?
-
Das ist eine php-seite die afaik ein png kreirt oder so.
Ich weis es nicht genau, aber es ist zu 100% ein png.
Hat jemand eine idee zur Lösung meines Problems?
-
speicher das bild auf platte und versuchs mal von da zu öffnen, wenn das geht, dann liegts warscheinlich an dem php zeugs
-
Das png auf der platte speichern und zu öffnen habe ich bereits gemacht.
Das geht alles wunderbar.
Ich hab jetzt als Test mal so ein Png hier hochgeladen.
Wenn ich den link in die ImageIO.read(..) Funktion einsetzte erhalte ich genau die gleiche Fehlermeldung
-
@boom: Dann versuch mal, nen kleinen Umweg zu gehen. Vielleicht klappt es ja über die Variante der Methode, die einen InputStream haben will. Schreib halt noch ein bischen Extracode, um an das Image über einen BufferedInputStream zu kommen.
-
Okay, vielen dank schonmal für die Hilfe.
Ich habe nun mit dem HttpClient mir das bild als InputStream besorgt.
Danach hab ich daraus ein BufferedImage gemacht und versucht zu speichern.[...] BufferedImage bi = ImageIO.read (is); ImageIO.write (bi, "png", new File ("bild.png"));
Jetzt bekomme ich allerdings die Fehlermeldung:
java.lang.IllegalArgumentException: im == null! at javax.imageio.ImageIO.write(Unknown Source) at javax.imageio.ImageIO.write(Unknown Source) at web.Web.getPng(Web.java:299) at main.Main.main(Main.java:17) Exception in thread "main"
Könnte es daran leigen, dass das Bild nicht gerendert ist?
Denn laut der java dokumentation erwartet die ImageIO.write(...) Funktion ein RenderedImage:
public static boolean write(RenderedImage im, String formatName, File output)
-
@boom: Guck mal, ob bi null ist.
-
Das ist viellciht komisch... Ich geb dir mal den code:
HttpClient httpclient = new HttpClient(); HttpMethod httpmethod = new GetMethod ("http://painpleasure.extra.hu/upload/test.png"); httpmethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(3, false)); InputStream is = null; try { // Execute the method. int statusCode = httpclient.executeMethod(httpmethod); if (statusCode != HttpStatus.SC_OK) { System.err.println("Method failed: " + httpmethod.getStatusLine()); } // Read the response body. is = httpmethod.getResponseBodyAsStream(); //provisorische Lösung zum Auslesen eines teils des pngs byte part[] = new byte [100]; is.read(part); String sPart = new String (part); System.out.println ("in try!"); System.out.println ("Bytes:" + sPart); } catch (HttpException e) { System.err.println("Fatal protocol violation: " + e.getMessage()); e.printStackTrace(); } catch (IOException e) { System.err.println("Fatal transport error: " + e.getMessage()); e.printStackTrace(); } finally { // Release the connection. httpmethod.releaseConnection(); } //////////////////////////////////////////////// BufferedImage bi = ImageIO.read (is); if (bi == null) System.out.println("bi = null!"); ImageIO.write (bi, "png", new File ("bild.png"));
Und wenn ich das jetzt ausführe, dann wird zwar ein teil des pngs ausgelesen (es sind zwar jede menge kästchen und anderes wirres zeug, aber es ist nicht nichts ). Allerdings unten geht mein Programm TROTZDEM noch in den System.out.println("bi = null!")-Block rein.
Das heisst im try-Block ist der Stream anscheinend noch nicht null, aber ausserhalb des try-Blocks anscheinend schon...
-
@boom: Auf jeden Fall solltest Du erstmal einen BufferedInputStream um Deinen InputStream herumbauen.
-
Und wie mach ich das genau?
ich hab gerade versucht, den InputStream einfach in einen BufferedInputStream zu konvertieren und diesen BufferedInputStream dann an die write-Funktion zu übergeben. Die Fehlermeldung bleibt die gleiche...
-
Ich hatte an sowas gedacht:
is = new BufferedInputStream(httpmethod.getResponseBodyAsStream());
Sag mal, kommentierst Du das "is.read(part);" eigentlich aus, wenn Du den Test für das richtige Bild machst?
-
okay, genau so hab ich das jetzt auch gemacht.
HttpClient httpclient = new HttpClient(); HttpMethod httpmethod = new GetMethod ("http://painpleasure.extra.hu/upload/test.png"); httpmethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(3, false)); InputStream is = null; try { // Execute the method. int statusCode = httpclient.executeMethod(httpmethod); if (statusCode != HttpStatus.SC_OK) { System.err.println("Method failed: " + httpmethod.getStatusLine()); } // Read the response body. is = httpmethod.getResponseBodyAsStream(); } catch (HttpException e) { System.err.println("Fatal protocol violation: " + e.getMessage()); e.printStackTrace(); } catch (IOException e) { System.err.println("Fatal transport error: " + e.getMessage()); e.printStackTrace(); } finally { // Release the connection. httpmethod.releaseConnection(); } //////////////////////////////////////////////// BufferedInputStream binputstream = new BufferedInputStream (is); BufferedImage bi = ImageIO.read (binputstream); if (binputstream == null) System.out.println("BufferedInputStream ist Null!"); if (bi == null) System.out.println ("BufferedImage ist Null!"); try { ImageIO.write (bi, "png", new File ("bild.png")); } catch (IllegalArgumentException e) { e.printStackTrace(); } } catch (IOException e) { e.printStackTrace(); }
Aber es geht immer noch nicht...
Das is.read(part) habe ich auskommentiert.