您如何有效地扩展JFrame的内容Java?

时间:2015-09-17 16:01:43

标签: java swing bufferedimage scaling

我正在寻找一种方法来正确缩放(几乎)所有JFrame的内容。到目前为止,我尝试过的所有解决方案都非常缺乏渲染速度。我正在寻找的速度类似于在智能手机上扩展内容时的速度。

即使您使用新内容透支JFrame,JFrame的内容也应该可以快速重新展开并保持缩放。它也应该足够灵活,这样你就可以选择哪个BufferedImage(这实际上是我绘制的唯一类型,我不会绘制任何其他"形状和## 34;)重绘。我正在使用普通的图形绘制,分别是。 Graphics2D对象。

我之前尝试过的是Graphic2D的缩放方法,并使用AffineTransformat对象单独缩放每个BufferedImage:

    g.scale(scalingFactorX, scalingFactorY);

或者:

    BufferedImage img = someImageToScale();
    AffineTransform scaleTransform = AffineTransform.getScaleInstance(scalingFactorX, scalingFactorY);
    AffineTransformOp bilinearScaleOp = new AffineTransformOp(scaleTransform,
            AffineTransformOp.TYPE_NEAREST_NEIGHBOR);

    return bilinearScaleOp.filter(img, new BufferedImage(targetWidth, targetHeight,
            BufferedImage.TYPE_INT_ARGB));

其中,scaleFactorX / Y是内容应按比例缩放的因子,而目标宽度为resp。 targetHeight表示BufferedImage的结果(缩放)维度。

两种方法都相当缓慢,这似乎是因为在这两种情况下,每个帧都必须重新计算内容的缩放版本。我觉得我在这里错过了一些非常明显的东西。

1 个答案:

答案 0 :(得分:4)

虽然drawImage()可以对图片进行重新取样,但每次调用 paintComponent()时都必须这样做。根据建议hereAffineTransformOp可让您选择插值类型;使用最快的,满足您的图像质量要求。在您对图像进行令人满意的重新采样后,请确保在特定Graphics上下文中进行渲染时不会无意中重新对图像进行重新采样。覆盖getPreferredSize()以使目标组件与重新采样的图像大小相同,如examples所示。

  

我的图片只有32x32,但有很多(~500)。

考虑使用flyweight pattern仅渲染可见图像。 JTableJList是示例,如here所述。

  

使用单独的组件是否具有性能优势或其他优势?

您可能需要原型和profile以确定,或许可以通过比较代表性示例:

  • 典型的基于组件的示例包括引用的基于按钮的游戏here,或者已审核的国际象棋游戏hereherehere

  • 基于图块的game引用here说明了单个图块面板和多个配件面板,它们都会听取常见的游戏模型。