2016-04-18 69 views
1

我正在試圖從URL加載這個image,但是收到像this這樣的圖像。Java。破損的圖像來自URL

代碼:

@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(); 
      } 

回答

2
  1. 不讀paintComponent方法中的圖像,它會讓你的應用程序出現低迷,因爲該方法是在事件調度線程(EDT)上執行。此外,無論何時重新繪製組件,都將重新閱讀,這意味着您將一遍又一遍地下載圖像。相反,可以在前面或單獨的線程中讀取它(即使用SwingWorker),並且只能從paintComponent方法中調用g.drawImage(...)

  2. 破壞圖像的原因是你的字節複製代碼,你不注意有多少字節被讀取(只要值不是-1),而是無條件複製512字節。不過,你不需要在這裏做,你可以簡單地流傳遞給ImageIO.read,這樣,使得代碼更簡單,更可讀:

    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); 
    } 
    

    添加額外try(嘗試與 - 資源)塊可以確保您的流也正確關閉以避免資源泄漏。

  3. 對於完整性,修復字節複製代碼,正確的版本是:

    // ... 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

我從網址到本地一些代碼拷貝文件..到目前爲止,結果是同樣喜歡實際的來源。只要做一些修改也許可以幫助解決它。

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

我不知道這是不是唯一的問題,但你可能會寫的比你多得到。 我建議你改變你編寫代碼來:

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

否則,如果最後一個緩衝區是不完全的512個字節長,你會寫太多