2011-12-02 21 views
1
時下載圖片,真快

假設我們有這個URL稱爲是它可以從一個網站使用JAVA

「mysite.com」

在這個網站,我們有一個具有約200目錄中稱爲圖像

。 PNG圖片

我想要通過這些圖片掃描一個接一個(可以預測圖片的URL,如果你知道前面的圖片的URL)中的程序,然後我想在我的JFrame顯示此圖像

我最初想到的是什麼克,因爲我知道網址,爲什麼我不瀏覽所有不同的圖像網址,然後做到這一點?

Image image = ImageIO.read(url); hasImage.setIcon(new 
    ImageIcon(image)); 

現在

hasImage 

是一個JLabel,我用的是我剛剛從URL下載

url 

是類URL的對象的圖像

so,everyt ime在一個循環中我找到了新的URL,並且我打電話給具有上面我剛剛發佈的兩行代碼的函數,以便更新標籤上的圖像

請注意,這兩行代碼位於按鈕內ActionListener,這樣每次點擊按鈕時,下一個圖像將會顯示。

這裏有1個主要問題。

當我想要顯示下一張圖片時,需要一些時間來創建新的url對象,下載圖片,然後將其顯示在我的標籤上,這很煩人,特別是如果您匆忙想要顯示圖像真的很快...

現在,我想到了另一個實現,爲什麼不只是下載所有的圖像,將它們保存在本地的某個地方,然後掃描存儲圖像的目錄並每次顯示它們按鈕被點擊?

好,我這樣做,但問題是,它需要超過一分鐘,以 下載的所有圖像後,它的作品順利,真快

所以這裏的大問題是,它需要這麼多時間下載圖像,所以它基本上是以前的實現,但在這一個,而不是等待一點點,當我按下按鈕,我有點等待下載,這需要相同的時間...

我的問題是,我怎樣才能讓它變得更快?如果它會下載所有的圖像在不到5秒鐘,我會滿足

這裏的功能我使用,以保存圖像

private void saveImages() { 
    Image image; 
    int ID = 1; 
    String destFile = "destFolder" + ID + ".png"; 

    try { 
     image = ImageIO.read(url); 
     ImageIO.write((RenderedImage) image, "png", new File(destFile)); 
    } catch (IOException ex) { 

    } 

    while (ID < 200) { 
     try { 
      String path = url.getPath(); 

      String[] token = path.split("-"); 
      String[] finalToken = token[2].split("\\."); 
      ID = Integer.parseInt(finalToken[0]); 
      url = new URL("http://somesite/images/" + (ID + 1) + ".png"); 


      destFile = "C:\\...\\destFolder\\" + ID + ".png"; 
      image = ImageIO.read(url); 
      ImageIO.write((RenderedImage) image, "png", new File(destFile)); 

     } catch (MalformedURLException ex) { 

      JOptionPane.showMessageDialog(null, 
        "URL is not in the correct form", "Malformed URL", 
        JOptionPane.ERROR_MESSAGE); 

     } catch (IOException ex) { 
     } 
    } 

    JOptionPane.showMessageDialog(null, "Images were loaded successfully", 
      "Success", JOptionPane.INFORMATION_MESSAGE); 
} 

編輯:順便說一下我對真的很抱歉代碼,這是一種混亂,這只是我打字的第一件事....我會稍後改變它,但我希望你能明白我現在面臨的問題:)

回答

3

無論是Java還是實施都是問題,這是您連接的速度。您可以下載應用程序所需的所有圖像(這需要一些時間,如果圖像未被查看則毫無意義),或者在點擊它們時加載它們。

如果您希望看起來更快一點,您可以開始將圖像加載到本地數據庫或文件系統(如緩存)中。這顯然有它的缺點,因爲一旦圖片加載一次,加載時間只會更快,而且通常不會有非常大的緩存。

您也可以在查看一張圖片時加載5張左右的前後圖片,這會讓用戶看起來更快。

1

從網上下載200張圖片總是需要一些時間。你需要做的是加快速度

  1. 爲了避免下載事件分派線程中的圖像:它會在下載時阻塞UI。圖像應該在單獨的後臺線程中下載。
  2. 要有兩個線程同時下載圖像。您可以並行下載更多,但大多數Web服務器拒絕來自同一主機的超過2個併發連接。
0

我會建議在後臺加載圖片,讓它們在加載後立即出現,這樣您的用戶界面就會有反應。當你去一個特定的圖像,你也可以自動加載下一個預期。

這是一個相當綠色的幹編碼(實際上並未嘗試編譯)嘗試,這應該證明這個想法。 (原諒緊密的耦合,並且在課堂上負起責任,而且,它對於無限的imageBuffer更加輕鬆,並且沒有卸載到磁盤)。

class ImageManager { 
    private ExecutorService asyncLoader = Executors.newFixedThreadPool(2); 
    private HashMap<Integer, Image> imageBuffer = new HashMap<Integer, Image>(); 
    private final int PRELOAD = 2; 
    private String baseUrl; 
    public ImageManager(String baseUrl) { 
    this.baseUrl = baseUrl; 
    } 
    public void loadImageAndUpdateLabel(final int idx, final JLabel label) { 
    asyncLoader.execute(new Runnable() { 
     public void run() { 
     loadSync(idx); 
     SwingUtilities.invokeLater(new Runnable() { 
      label.setIcon(new ImageIcon(imageBuffer.get(idx))); 
      label.setText(null); 
     }); 
     } 
    }); 
    triggerAsyncPreload(idx);   
    } 
    public void triggerAsyncPreload(int idx) { 
    for (int i=idx-PRELOAD; i<idx+PRELOAD; i++) { 
     if (i>0) { 
     loadAsync(i); 
     } 
    } 
    } 
    public synchronized void loadSync(int idx) { 
    if (imageBuffer.get(idx) == null) { 
     imageBuffer.put(idx, ImageIO.read(new URL(baseUrl, idx+".png"))); 
    } 
    } 
    public void loadAsync(final int idx) { 
    asyncLoader.execute(new Runnable() { 
     public void run() { 
     loadSync(idx); 
     } 
    }); 
    } 
} 

class ... { 
    ... 
    private int currentImageIdx = 0; 
    private ImageManager imageManager = new ImageManager("http://site.com/images/"); 
    private JLabel label = new JLabel(); 
    private JButton nextImageButton = new JButton(new AbstractAction("Next image") { 
    public void actionPerformed(ActionEvent e) { 
     currentImageIdx++; 
     label.setIcon(null); 
     label.setText("Loading image "+currentImageIdx); 
     imageManager.loadImageAndUpdateLabel(currentImageIdx, label); 
    } 
    }); 
    ... 
} 
相關問題