是否有一个内存效率的替代graphics.drawImage()?

时间:2013-10-28 11:30:09

标签: java image swing memory scale

我需要在内存中保存~50张图像(这是必须的,我无法改变的条件)。但是,在某些时候我想在JFrame上绘制这些图像的缩略图。

使用

graphics.drawImage(picture, 100, 100, 100, 100, null);

绘制调整大小的图像版本效果很好,因为这样做不会消耗(或非常稀疏)内存。但众所周知,drawImage中的缩放算法并不是最好的,看起来很差。

我已经尝试过Thumbnailator,JMagick和imgscalr来生成质量更好,外观整洁的缩略图结果。但是,存在一个问题:它们的调用会消耗一些内存,因为它们正在创建新的BufferedImage对象。

话虽如此,下面的代码几乎保持不变的内存使用情况:

BufferedImage i = null;
JFrame frame = new JFrame();
frame.setSize(500, 500);
frame.setVisible(true);

try {
    i = ImageIO.read(new File("season.jpg"));
} catch (IOException e1) {}

while (true)
{
    frame.getGraphics().drawImage(i, 100, 100, 100, 100, null);

    try {
    Thread.sleep(1000);
    } catch (InterruptedException e) {}
}

但是,以下代码将继续上升并上升并增加内存消耗:

BufferedImage i = null;
JFrame frame = new JFrame();
frame.setSize(500, 500);
frame.setVisible(true);

try {
    i = ImageIO.read(new File("season.jpg"));
} catch (IOException e1) {}

while (true)
{
    BufferedImage x;
    try {
        x = Thumbnails.of(i).size(100, 100).keepAspectRatio(false).asBufferedImage();
        frame.getGraphics().drawImage(x, 100, 100,  null);
    } catch (IOException e1) {}

    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {}
}

所以,我要问的是:

有吗? a)一个良好的内存效率替代方案,可以将调整大小的图像版本绘制到JFrame中? 要么 b)是否可以就地调整图像大小,操纵内部结构而不创建新的图像对象(例如:scaleInPlace(图像,100,100)而不是图像=比例(图像,100,100))?

感谢您的帮助! :)

PS:我知道我的代码示例不是将图像绘制到JFrame的推荐方法,它只是一个简单的例子。

1 个答案:

答案 0 :(得分:2)

  1. 在此contianer不包含JComponent的情况下使用JLabel中的Icon / ImageIcon,您可以使用getScaledInstance来存储具有(仅)合理像素比率的图像,然后再使用内存请求,然后可以将这些图像存储在局部变量中

  2. frame.getGraphics().drawImage(x, 100, 100, null);不正确的方式,今天的Swing需要将JPanel(覆盖getPreferredSize)和paitComponent放在那里} drawImage来自getScaledInstance

  3. 存储为本地变量
  4. getScaledInstance非常异步,