2016-04-18 18 views
1

Ich versuche, dieses von der URL zu laden, aber erhält Bild wie this.Java. Unterbrochenes Bild von URL

Code:

@Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2 = (Graphics2D)g; 
      ByteArrayOutputStream out = new ByteArrayOutputStream(); 
      try { 
       URL url = new URL("http://s.developers.org.ua/img/announces/java_1.jpg"); 
       BufferedInputStream in = new BufferedInputStream(url.openStream()); 
       byte[] b = new byte[512]; 
       while (in.read(b)!=-1) 
        out.write(b); 
       Image img = ImageIO.read(new ByteArrayInputStream(out.toByteArray())); 
       g2.drawImage(img, 0, 0, getWidth(), getHeight(), null); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 

Antwort

2
  1. Bilder Lesen Sie nicht in der paintComponent Methode, wird es Ihre Anwendung erscheint träge machen, da das Verfahren auf dem Event-Dispatcher-Thread (EDT) ausgeführt wird. Außerdem wird es erneut gelesen, wenn Ihre Komponente neu gezeichnet wird, was bedeutet, dass Sie das Bild immer wieder herunterladen. Lesen Sie es stattdessen vorne oder in einem separaten Thread (verwenden Sie zum Beispiel SwingWorker) und rufen Sie g.drawImage(...) nur innerhalb der paintComponent Methode auf.

  2. Der Grund für das gebrochene Bild ist Ihr Byte Kopieren Code, wo man nicht darauf achten, wie viele Bytes gelesen werden (solange der Wert nicht -1 ist), sondern kopiert bedingungslos 512 Bytes. Allerdings brauchen Sie nicht, dass hier zu tun, können Sie einfach den Strom zu ImageIO.read passieren, wie dies, so dass der Code einfacher und besser lesbar:

    URL url = new URL("http://s.developers.org.ua/img/announces/java_1.jpg"); 
    try (BufferedInputStream in = new BufferedInputStream(url.openStream())) { 
        BufferedImage img = ImageIO.read(in); 
    } 
    

    Hinzufügen der zusätzlichen try (Try-mit-Ressourcen) Block stellt sicher, dass Ihr Stream auch ordnungsgemäß geschlossen ist, um Ressourcenverluste zu vermeiden.

  3. Für Vollständigkeit, die Byte-Kopier Code zu beheben, wäre die richtige Version sein:

    // ... as above ... 
    byte[] b = new byte[512]; 
    int bytesRead; // Keep track of the number of bytes read into 'b' 
    while ((bytesRead = in.read(b)) != -1) 
        out.write(b, 0, bytesRead); 
    
0

ich Local einige Code Kopie von einer URL haben .. Bisher das Ergebnis ist das gleiche wie tatsächliche Quelle. Tun Sie einfach etwas Änderung vielleicht kann helfen, es zu lösen.

import java.awt.Image; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import java.net.URL; 
import java.util.ArrayList; 
import org.apache.commons.io.FilenameUtils; 
import javax.imageio.ImageIO; 

public class ImagesUrlToImagesLocal { 
    public ArrayList<String> getIt(ArrayList<String> urlFile) 
    { 
     ArrayList<String> strResult = new ArrayList<String>(); 
     Image imagesUrl = null; 
     String baseName = null; 
     String extension = null; 
     File outputfile = null; 
     try { 
      for (int i = 0; i < urlFile.size(); i++) 
      { 
       URL url = new URL(urlFile.get(i)); 
       baseName = FilenameUtils.getBaseName(urlFile.get(i)); 
       extension = FilenameUtils.getExtension(urlFile.get(i)); 
       imagesUrl = ImageIO.read(url); 
       BufferedImage image = (BufferedImage) imagesUrl; 
       outputfile = new File("temp_images/" + baseName + "." + extension); 
       ImageIO.write(image, extension, outputfile); 
       strResult.add("temp_images/" + baseName + "." + extension); 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     return strResult; 
    } 
} 
1

Ich weiß nicht, ob dies das einzige Problem ist, aber Sie könnten mehr als Sie schreiben bekommen. Ich schlage vor, dass Sie Ihr Schreiben von Code ändern:

int len; 
while ((len=in.read(b))!=-1) 
    out.write(b, 0, len); 

Andernfalls, wenn der letzte Puffer nicht genau 512 Bytes lang ist, Sie zu viel

schreiben werde