在这种情况下使用缓存生成的BufferedImages?

时间:2012-11-20 05:04:48

标签: java swing caching jscrollpane bufferedimage

我正在实施一个棋盘游戏,其中每个玩家都有几个单位,每个单位都是使用我使用以下方法从文件中读取的公共图像向用户显示的。我在应用程序启动时读取了这个图像,并将在以后使用它。

    private static BufferedImage readBufferedImage (String imagePath) {
        try {
            InputStream is = IconManager.class.getClassLoader().getResourceAsStream(imagePath);
            BufferedImage bimage = ImageIO.read(is);
            is.close();
            return bimage;
        } catch (Exception e) {
            return null;
        }
    }

单位因位于该常见图片顶部的各种彩色标记而异。

在我向JPanel添加几个commonImages之前,令牌是使用漂浮在commonImage顶部的JLabel实现的

    //at startup
    ImageIcon commonImage = new ImageIcon(readBufferedImage("image.png"));
    ...
    JPanel panel = new JPanel();
    panel.add(commonImage);
    panel.add(commonImage);

    //located JLabels with token on the top of each commonImage        

但是,现在我想使用JScrollPane而不是JPanel,所以我认为在向用户展示之前,将drawString()和drawImage()更好地用于每个commonImage。

我估计大约有20个单位为20个。所以现在每个单位的每一个转弯我需要动态生成具有各种令牌配置的BufferedImage。

问题是我是否应该根据令牌配置缓存已生成的BufferedImages,以便在使用相同配置之前生成图像时从缓存中提取?

1 个答案:

答案 0 :(得分:1)

你问的问题取决于几个因素:

  1. 从头开始生成图片需要多长时间
  2. 检查图像是否在
  3. 之前生成所需的时间
  4. 每张图片的大小
  5. 图像重复使用的概率
  6. 因此,如果不了解您的申请,任何人都无法为您提供准确的答案。

    一般情况下,如果您只是移动令牌,应该快速实现图纸面板的updatepaintComponent方法。如果您保存基本图像,令牌图像和当前生成的图像(基本上是您提出的),我不会预料到性能问题。关键是要在自定义update方法中更新图像,并始终使用paintComponent方法绘制当前结果图像。

    <强>更新

    例如,您可以使用与此类似的代码缓存当前显示:

    private BufferedImage cachedImage;
    ...
    
    @Override
    public void paintComponent(Graphics g){
        //If the image needs to be refreshed draw it to the cache first
        if(cachedImage == null){
            cachedImage = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
            super.paintComponent(cachedImage.getGraphics());
        }
    
        //Draw the image from cache
        g.drawImage(cachedImage, 0, 0, this);
    }
    

    如果要清除缓存,请在执行更新的方法中设置cachedImage = null;

    但在你的情况下,

    • 您遇到的200x200规模的任何性能问题都与您正在进行的绘图数量有关。因为我猜你不关心帧/秒速率,我怀疑你会遇到性能问题(你可以收集时间来确切地知道绘制需要多长时间 - 我猜不到100毫秒)< / LI>
    • 最简单的做法是缓存令牌及其字符串的图像(我假设它们很少更改),但仍然动态创建令牌的布局。 (在你的情况下任何其他性能提升都不会那么容易)。
    • 缓存之前的屏幕渲染将基本上打破摇摆显示模型(使用它没有多大意义 - 只需自己进行布局)。这实际上适用于容器的几乎所有缓存。