java读取图片缩略方法_java – 制作jfilechooser显示图像缩略图

尽管使用原生的外观和放大器,我还是很惊讶地看到了这一点.感觉在Windows中,文件选择器确实没有缩略图视图.我尝试了你的例子,你沿着正确的方向前进,但我看到有很多大图像的文件夹有多慢.当然,开销是由于读取文件内容然后解释图像时的I / O,这是不可避免的.

更糟糕的是,我发现FileView.getIcon(File)被大量调用 – 在显示文件列表之前,当鼠标悬停在图标上以及选择更改时.如果我们在加载后不缓存图像,我们将无意义地重新加载图像.

显而易见的解决方案是将所有图像加载推送到另一个线程或线程池,一旦我们得到缩小的结果,将其放入临时缓存中,以便可以再次检索它.

我经常使用Image和ImageIcon,我发现可以通过调用setImage(Image)随时更改ImageIcon的图像.这对我们来说意味着,在getIcon(File)中,我们可以立即返回一个空白或默认图标,但保留对它的引用,将其传递给工作线程,该工作线程将在后台加载图像并设置图标的图像后来当它完成时(唯一的问题是我们必须调用repaint()来查看更改).

对于此示例,我使用的是ExecutorService缓存线程池(这是获取所有图像的最快方法,但使用大量I / O)来处理图像加载任务.我也使用WeakHashMap作为缓存,以确保只要我们需要它们就只保留缓存的图标.您可以使用其他类型的Map,但是您必须管理您保留的图标数量,以避免内存不足.

package guitest;

import java.awt.Image;

import java.awt.image.BufferedImage;

import java.io.File;

import java.util.Map;

import java.util.WeakHashMap;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.regex.Pattern;

import javax.swing.Icon;

import javax.swing.ImageIcon;

import javax.swing.JFileChooser;

import javax.swing.SwingUtilities;

import javax.swing.UIManager;

import javax.swing.filechooser.FileView;

public class ThumbnailFileChooser extends JFileChooser {

/** All preview icons will be this width and height */

private static final int ICON_SIZE = 16;

/** This blank icon will be used while previews are loading */

private static final Image LOADING_IMAGE = new BufferedImage(ICON_SIZE,ICON_SIZE,BufferedImage.TYPE_INT_ARGB);

/** Edit this to determine what file types will be previewed. */

private final Pattern imageFilePattern = Pattern.compile(".+?\\.(png|jpe?g|gif|tiff?)$",Pattern.CASE_INSENSITIVE);

/** Use a weak hash map to cache images until the next garbage collection (saves memory) */

private final Map imageCache = new WeakHashMap();

public static void main(String[] args) throws Exception {

UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

JFileChooser chooser = new ThumbnailFileChooser();

chooser.showOpenDialog(null);

System.exit(1);

}

public ThumbnailFileChooser() {

super();

}

// --- Override the other constructors as needed ---

{

// This initializer block is always executed after any constructor call.

setFileView(new ThumbnailView());

}

private class ThumbnailView extends FileView {

/** This thread pool is where the thumnnail icon loaders run */

private final ExecutorService executor = Executors.newCachedThreadPool();

public Icon getIcon(File file) {

if (!imageFilePattern.matcher(file.getName()).matches()) {

return null;

}

// Our cache makes browsing back and forth lightning-fast! :D

synchronized (imageCache) {

ImageIcon icon = imageCache.get(file);

if (icon == null) {

// Create a new icon with the default image

icon = new ImageIcon(LOADING_IMAGE);

// Add to the cache

imageCache.put(file,icon);

// Submit a new task to load the image and update the icon

executor.submit(new ThumbnailIconLoader(icon,file));

}

return icon;

}

}

}

private class ThumbnailIconLoader implements Runnable {

private final ImageIcon icon;

private final File file;

public ThumbnailIconLoader(ImageIcon i,File f) {

icon = i;

file = f;

}

public void run() {

System.out.println("Loading image: " + file);

// Load and scale the image down,then replace the icon's old image with the new one.

ImageIcon newIcon = new ImageIcon(file.getAbsolutePath());

Image img = newIcon.getImage().getScaledInstance(ICON_SIZE,Image.SCALE_SMOOTH);

icon.setImage(img);

// Repaint the dialog so we see the new icon.

SwingUtilities.invokeLater(new Runnable() {public void run() {repaint();}});

}

}

}

已知的问题:

1)缩放时我们不保持图像的宽高比.这样做可能会导致图标具有奇怪的尺寸,从而破坏列表视图的对齐方式.解决方案可能是创建一个16×16的新BufferedImage,并在其上方渲染缩放图像,居中.如果你愿意,你可以实现!

2)如果文件不是图像或已损坏,则根本不会显示任何图标.看起来程序只在渲染图像时检测到这个错误,而不是在我们加载或缩放它时,所以我们无法提前检测到.但是,如果我们解决问题1,我们可能会检测到它.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值