2012-07-25 40 views
2

我正在编写一个程序,涉及到许多图像的自定义搜索。当用户输入他们的搜索条件时,相应的图像将从缓存或服务器中获取。我有一个显示指向相应图像的链接的JTable。当用户点击链接时,图像显示在JPanel上。点击链接时,我可以从硬盘读取图像,但速度并不像我想的那么快。加载它需要几秒钟的时间。我已经尝试创建一个BufferedImage数组,但如果搜索返回许多结果,我去奥姆。我想知道什么是点击链接时更快速地显示图像的最佳方式。在java中加载很多缓冲图像100+到内存

继承人我如何获取图片...

Public void getFile(String fileName){ 
File file = new File("./cache/"+fileName); 
    boolean exists = file.exists(); 

    BufferedImage returnImage =null; 
    if(exists){ 
     try { 

      returnImage = ImageIO.read(file); 
      System.out.println("Found In Cache!"); 
     } catch (IOException|IndexOutOfBoundsException e) { 
      try { 
       if(fileName != null){ 
       returnImage = downloadImage(fileName); 
       System.out.println("Found ON Server :("); 
       } 
      } catch (IOException |IndexOutOfBoundsException ex) { 
       // TODO Auto-generated catch block 
       ex.printStackTrace(); 
      } 
     } 
    }else{ 
     try { 
      if(fileName != null){ 
      returnImage = downloadImage(fileName); 
      System.out.println("Found ON Server :("); 
      } 
     } catch (IOException |IndexOutOfBoundsException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 
    return returnImage; 

} 
} 

而这正是我把它们放在一个数组...

BufferedImage[] images = new BufferedImage[numOfSearchResults]; 

for(SearchResult r: results){ 
    images[i] = imageCache.getFile(r.imageName); 
} 

基本上我只是想知道会是什么最好的方式来预先加载图像,而不会发生。提前致谢

+0

从磁盘加载图像并显示它不应该花费几秒钟,除非它是一个非常大的图像(磁盘空间很大尺寸)。你有没有分析你的应用程序,看看图像加载是否确实是瓶颈? – Robin 2012-07-25 16:14:40

+0

什么是奥姆? – 2012-07-25 16:15:52

+0

@SteveKuo我编辑了包含正确的标记。 – 2012-07-25 16:16:14

回答

3

从磁盘加载图像需要几秒钟的时间,除非图像真的真的是BIG(10万像素或更多),这听起来不合理。首先确定时间的真正用处。

对于缓存,您可以持有对使用java.lang.ref.SoftReference加载的每个图像的引用 - 这允许您在运行OOM之前在之前对图像进行垃圾回收。 如果真的不可避免,我会使用多层缓存系统,第一级使用内存中的SoftReferences,而基于服务器的映像使用额外的磁盘缓存。在查找映像时,首先检查内存中的缓存,如果没有发现任何内容,则检查磁盘缓存,如果仍未找到,则以常用方式加载映像。

+1

图像相当大3300 x 2550我用较小的图像测试它,它们很快从磁盘读取。谢谢 – Gamplod 2012-07-25 16:37:53

+0

是否可以只加载图像的一部分?在这种大小和全分辨率下,不可能显示所有的图像,所以不妨像Photoshop那样加载一个图块。 – 2013-03-21 02:35:57

+1

@JamesPoulson那么,TC没有说他使用的是什么图像格式,但对于通常的疑问JPG,PNG等,除非你编写自己的图像解码器,否则没有太多可以做的事情(我怀疑你可以获得多少) 。 Photoshop btw。 *也*加载整个图像。平铺方法随后用于在处理图像时将图像的各个部分交换到磁盘。它不能直接在通用的图像文件上使用,比如说PNG。 – Durandal 2013-03-21 16:48:26

2

请勿加载所有/太多图像,在当前索引之前加载耦合图像,并在当前索引之后耦合图像。

将图像加载器实现为不阻止主执行线程并在用户正在观看当前加载的图像时加载额外图像的另一个线程。

+0

我可能会看看Executors API的这个 – MadProgrammer 2012-07-25 16:21:24

0

您可以打开所有图像的InputStream并关闭用户未点击的图像,然后使用您需要的图像。

通过这种方式,您不必缓冲所有图像,但在用户点击时已将它们放在“可触及范围内”。

但是@Robin已经正确评论了,它真的不需要很长时间才能加载平均大小的图片。

我不确定这是否会让您获得更多的表现,但取决于您的情况,它可以。

0

如果您不需要全尺寸图像,我会在加载时缩小它们以减少内存量。您必须记住,内存中加载的图像不再被压缩。

如果您可以控制源图像,我会考虑生成缩略图以帮助它们加载更快。我们使用的是200x200,&的缩略图,即使在基于SMB的共享上,他们也只需要一秒钟的时间来加载