我创建了一个SWING组件JImageEditor,它只显示一张图片。我们的想法是在未来的道路上为组件添加更多功能。
我已经实现的一项功能是缩放。现在,这部分在paintComponent()方法中得到了解决。但是,不知怎的,我怀疑这可能是个坏主意,因为这意味着每次调用paintComponent()时图像都会从原始大小缩放到当前的“缩放大小”。 paintComponent代码如下:
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BICUBIC);
int w = getWidth();
int h = getHeight();
double imageWidth = scale * image.getWidth();
double imageHeight = scale * image.getHeight();
double x = (w - imageWidth) / 2;
double y = (h - imageHeight) / 2;
AffineTransform at = AffineTransform.getTranslateInstance(x, y);
at.scale(scale, scale);
g2.drawRenderedImage(image, at);
}
现在,我作为替代方案是保留两个BufferedImage实例,其中一个是原始实例,一个是当前“视图”。这样,无论何时调用setScale()方法,我都可以处理实际的缩放/缩放,而不是在paintComponent()中进行缩放。但是,缺点是我需要保留两个BufferedImage实例,这将导致更高的内存消耗,具体取决于图像大小。当然,无法预测任何给定用户使用该组件打开的大图像。
我正在寻找的是如果我在工作中走上正轨,或者竖起大拇指,如果设计不好,应该考虑其他一些解决方案。我感谢所有的投入,并将奖励所有启发我的答案: - )
答案 0 :(得分:3)
我会说在paintComponent中放置一个计时部分来测量它需要多长时间。从现有的基础上获得基础衡量标准。然后使用额外的BufferedImage实现优化方法。比较测量值并选择较小的测量值。我有一种感觉,你的直觉是正确的,做仿射转换每个绘制周期都很慢,并通过为缩放图像创建双缓冲区,源将更快。虽然我找不到任何确认或否认这一点的东西,但它可能会受到硬件加速的影响。
如果您将该部分代码提取到ZoomableBufferedImage类中,则可以轻松打开或关闭优化/未优化版本。 ZoomableBufferedImage将保存对源图像的引用,并包含一个额外的缓冲图像,它可以保持缩放版本。当您放大/缩小ZoomableBufferedImage根据其设置绘制到缓冲区时,然后在它的绘制方法中它可以从缓冲区中绘制,也可以将AffineTransform应用于源并根据其设置进行绘制。