使用JAVA时,是否可以从网站上快速下载图像
假设我们有一个叫做 mysite.com 在这个站点中,我们有一个名为images的目录,其中包含大约200个.PNG图片 我想制作一个程序,逐个扫描这些图片如果你知道前一张图片的URL,你可以预测图片的URL,然后我想在我的JFrame上显示这张图片 我最初想做的是,既然我知道URL,为什么我不扫描所有不同的图像URL,然后这样做呢使用JAVA时,是否可以从网站上快速下载图像,java,image,web,download,Java,Image,Web,Download,假设我们有一个叫做 mysite.com 在这个站点中,我们有一个名为images的目录,其中包含大约200个.PNG图片 我想制作一个程序,逐个扫描这些图片如果你知道前一张图片的URL,你可以预测图片的URL,然后我想在我的JFrame上显示这张图片 我最初想做的是,既然我知道URL,为什么我不扫描所有不同的图像URL,然后这样做呢 Image image = ImageIO.read(url); hasImage.setIcon(new ImageIcon(image)); 现在
Image image = ImageIO.read(url); hasImage.setIcon(new
ImageIcon(image));
现在
是一个JLabel,我使用刚从URL下载的图像
及
是类URL的对象
因此,每次在循环中,我都会找到新的URL,并调用包含我刚才发布的两行代码的函数,以便更新标签上的图像
请注意,这两行在按钮ActionListener中,因此每次单击按钮时,都会显示下一个图像
这里有一个主要问题
当我想显示下一幅图像时,需要花费一些时间来创建新的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);
}
编辑:顺便说一句,我真的很抱歉,代码有点乱,这只是我键入的第一件事。。。。稍后我会对其进行改进,但我希望您了解我现在面临的问题:Java或实现都不是问题,而是连接的速度。要么下载应用程序所需的所有图像,这需要一些时间,如果图像未被查看则毫无意义,要么在单击图像时加载图像 如果您想让它看起来快一点,您可以开始将映像加载到本地数据库或文件系统中,就像缓存一样。这显然有它的缺点,因为一旦一张图片被加载一次,它只会使加载速度加快,而且通常不需要非常大的缓存
您还可以在仅查看一幅图像时加载五幅左右的下一幅和上一幅图像,这将使用户感觉它更快 Java和实现都不是问题所在,而是连接的速度。要么下载应用程序所需的所有图像,这需要一些时间,如果图像未被查看则毫无意义,要么在单击图像时加载图像 如果您想让它看起来快一点,您可以开始将映像加载到本地数据库或文件系统中,就像缓存一样。这显然有它的缺点,因为一旦一张图片被加载一次,它只会使加载速度加快,而且通常不需要非常大的缓存
您还可以在仅查看一幅图像时加载五幅左右的下一幅和上一幅图像,这将使用户感觉它更快 从网上下载200张图片总是需要一些时间。你需要做的是加快速度 为了避免在事件分派线程中下载图像:它在下载时会阻塞UI。图像应该在单独的背景线程中下载。 让两个线程同时下载图像。您可以并行下载更多内容,但大多数web服务器拒绝来自同一主机的2个以上并发连接。
从网上下载200张图片总是需要一些时间。你需要做的是加快速度 为了避免在事件分派线程中下载图像:它在下载时会阻塞UI。图像应该在单独的背景线程中下载。 让两个线程同时下载图像。您可以并行下载更多内容,但大多数web服务器拒绝来自同一主机的2个以上并发连接。
我建议在后台加载图像,并让它们在加载后立即显示,这样您的UI就会响应。当您转到特定图像时,您也可以自动加载预期的下一个图像 这是一个相当绿色的干编码,实际上并没有尝试过comp 我试着这样做,应该能证明这个想法。原谅课程中的紧密耦合和混乱的职责。此外,它对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);
}
});
...
}
我建议在后台加载图像,并让它们在加载后立即显示,这样您的UI就会响应。当您转到特定图像时,您也可以自动加载预期的下一个图像 这里有一个相当绿色的干代码,实际上并没有试图编译,这应该可以证明这个想法。原谅课程中的紧密耦合和混乱的职责。此外,它对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);
}
});
...
}
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);
}
});
...
}