8

我是一位经验丰富的 Java 程序员,但对 Java2D 来说相对较新。我正在尝试缩放图像,但结果质量很差。该图像是面板的预览,因此包含文本和文本字段等内容。我会一直缩小,从不放大。

目前我正在使用以下代码: -

g.drawImage(panelImage, 0, 0, scaledWidth, scaledHeight, null);

其中 panelImage 是全尺寸预览 (BufferedImage),scaledWidth 和 scaledHeight 是各自的目标尺寸。我似乎在文本和文本字段等内容的边缘丢失了很多细节。

我应该使用更好的调用来缩放图像吗?

谢谢,约翰

4

4 回答 4

11

我可以提出的建议是首先将图像调整为单独的BufferedImage. 原因是,为了产生更好质量的缩放图像,可以获得一个Graphics2D对象。BufferedImage

Graphics2D可以接受“渲染提示”,它指示对象应执行图像处理的方式Graphics2D。该setRenderingHint方法是可用于设置那些渲染提示的方法之一。RenderingHints可以使用类中的渲染提示。

然后,使用该Graphics2D对象,可以BufferedImage使用之前指定的渲染提示将图像绘制到该对象。

粗略(未经测试)的代码将按以下方式工作:

BufferedImage scaledImage = new BufferedImage(
    scaledWidth,
    scaledHeight,
    BufferedImage.TYPE_INT_RGB
);

Graphics2D g = scaledImage.createGraphics();
g.setRenderingHints(
    RenderingHints.Key.KEY_INTERPOLATION,
    RenderingHints.VALUE_INTERPOLATION_BICUBIC
);

g.drawImage(panelImage, 0, 0, scaledWidth, scaledHeight, null);
g.dispose();

其他感兴趣的渲染提示可能包括:

The Java Tutorials 的控制渲染质量部分也有更多关于如何控制Graphics2D对象渲染质量的信息。

对于一般处理图形界面的非常好的信息来源,强烈推荐 Chet Haase 和 Romain Guy 的Filthy Rich Clients 。书中有一节涉及缩放图像的问题,这似乎很相关。

于 2009-05-31T17:28:54.250 回答
2

也许你应该打电话:

 g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);

g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
于 2009-05-31T17:25:04.537 回答
1

Coobird 是正确的,您需要逐步缩小(最好使用 BICUBIC)以获得足够小的缩略图的美观结果。Image.getScaledInstance 曾经使用 AREA_AVERAGED 方法来做到这一点,但它比 Chris Campbell 在他的“Image.getScaledInstance() 的风险”一文中最初提出的增量缩减要慢得多。

请原谅这里的自我推销,但是当涉及到图像缩放时,我将一些“原生 Java 最佳实践”放入了一个名为imgscalr的库中。

它在 Apache 2 许可下可用,源代码都在 GitHub 上;该库的目标是使本机 Java 中的图像缩放变得非常容易(1 个类,5 个静态方法)并确保获得最佳外观(这是您最初想要的),最快的结果(在大图像之间缩放时很棒) 或两者之间的平衡,让图书馆决定使用哪一个。

我只是想要一个可以“调整我的图像大小并避开我的方式”的库,并且在阅读了所有这些帖子几天后,当我解决了痛点(我自己也是如此)之后,我只是回过头来为任何人分享工作否则它可能会有所帮助。

于 2010-12-29T07:44:52.343 回答
0

酷鸟有正确的想法。我也会尝试RenderingHints.VALUE_INTERPOLATION_BILINEAR插值,看看它是否更好看。不过,在升级时双三次效果更好。为了在缩小规模时获得最佳结果,应该分几个步骤缩小规模。首先将分辨率减半,然后再减半,依此类推,直到接近所需的分辨率(即不能减半,否则图像会变得太小)。最后一步是缩小到所需的分辨率。

例如,假设您的输入图像是800x600并且您希望缩小到160x120

  1. 缩小50%。--> 400x300
  2. 缩小50%。--> 200x150
  3. 缩小到160x120
于 2009-05-31T17:53:23.197 回答