можно ли загружать изображения с веб-сайта очень быстро при использовании JAVA - PullRequest
1 голос
/ 03 декабря 2011

предположим, что у нас есть этот URL-адрес

"mysite.com"

. На этом сайте у нас есть каталог с изображениями, содержащий около 200 изображений PNG

Я хочусоздать программу, которая просматривает эти изображения одну за другой (вы можете предсказать URL-адрес изображения, если вы знаете URL-адрес предыдущего изображения), а затем я хочу отобразить это изображение на моем JFrame

, что я изначально думал делатьбыло, так как я знаю URL, почему бы мне просто не просканировать все URL разных изображений, а затем сделать это?

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

сейчас

 hasImage

- это JLabel, гдеЯ использую изображение, которое я только что загрузил с URL

и

url

- это объект класса URL

, поэтому каждый раз в цикле я нахожу новый URLи я вызываю функцию с двумя строками кода, которые я только что опубликовал выше, чтобы обновить изображение на моем ярлыке

, обратите внимание, что эти две строки находятся внутри кнопки ActionListener, так что каждый раз, когда я нажимаюна кнопке следующее изображение будетisplayed

здесь есть одна серьезная проблема.

когда я хочу отобразить следующее изображение, требуется некоторое время, чтобы создать новый объект 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);
}

РЕДАКТИРОВАТЬ: Btw I 'мне очень жаль код, он немного грязный, я набрал только первое ... я изменю его позже в лучшую сторону, но надеюсь, вы поймете, с какой проблемой я сталкиваюсь сейчас:)

Ответы [ 3 ]

3 голосов
/ 03 декабря 2011

Ни Java, ни реализация не являются проблемой, это скорость вашего соединения. Либо вы загружаете все изображения, которые требуются приложению (что занимает некоторое время и бессмысленно, если изображения не просматриваются), либо вы загружаете их по мере нажатия.

Если вы хотите, чтобы это выглядело немного быстрее, вы можете начать загрузку изображений в локальную базу данных или файловую систему (например, в кеш). Это, очевидно, имеет свои недостатки, поскольку ускоряет загрузку только после однократной загрузки изображения, и часто идеально не иметь очень большой кэш.

Вы также можете загрузить пять или около того следующих и предыдущих изображений при просмотре только одного изображения, что сделает его более быстрым для пользователя.

1 голос
/ 03 декабря 2011

Загрузка 200 изображений из Интернета всегда займет некоторое время.Чтобы ускорить это, вам нужно сделать

  1. Чтобы избежать загрузки изображений в потоке отправки событий: он блокирует пользовательский интерфейс во время загрузки.Изображения должны быть загружены в отдельном фоновом потоке.
  2. Чтобы два потока загружали изображения одновременно.Вы можете загружать больше параллельно, но большинство веб-серверов отклоняют более 2 одновременных подключений с одного хоста.
0 голосов
/ 03 декабря 2011

Я бы посоветовал загружать изображения в фоновом режиме и отображать их сразу после загрузки, чтобы ваш пользовательский интерфейс реагировал на них.Когда вы переходите к определенному изображению, вы также можете автоматически загружать следующие изображения в ожидании.

Вот довольно зеленая попытка с сухим кодом (на самом деле не пыталась скомпилировать), которая должна продемонстрировать эту идею.(Простите за тесную связь и довольно растоптанную ответственность на уроках. Кроме того, она довольно кавалерна по поводу неограниченности 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);
    }
  });
  ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...