我是一位经验丰富的Java程序员,但对Java2D来说相对较新。我正在尝试缩放图像但我的质量结果质量很差。图像是面板的预览,因此包含文本和文本字段等内容。我会一直缩小规模,永远不会起来。
目前我正在使用以下代码: -
g.drawImage(panelImage, 0, 0, scaledWidth, scaledHeight, null);
其中panelImage是全尺寸预览(BufferedImage),scaledWidth和scaledHeight是相应的目标尺寸。我似乎在文本和文本域之类的东西中丢失了很多细节。
我应该使用更好的电话来缩放图像吗?
谢谢, 约翰
答案 0 :(得分:11)
我可以提出的建议是先将图片调整为单独的BufferedImage
。原因是,可以获得BufferedImage
的{{3}}对象,以便生成质量更好的缩放图像。
Graphics2D
可以接受“渲染提示”,指示Graphics2D
对象应该执行图像处理的方式。 Graphics2D
方法是可用于设置这些呈现提示的方法之一。可以使用setRenderingHint
类的渲染提示。
然后,使用该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的KEY_RENDERING
部分还提供了有关如何控制Graphics2D
个对象的渲染质量的更多信息。
对于一般处理图形界面的非常好的信息来源,强烈建议使用Chet Haase和Romain Guy Controlling Rendering Quality。本书的一部分涉及缩放图像的问题,这似乎非常相关。
答案 1 :(得分:2)
可能你应该致电:
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
和
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
答案 2 :(得分:1)
Coobird是正确的,您需要逐步缩小(最好使用BICUBIC)以获得足够小的缩略图的漂亮效果。 Image.getScaledInstance用于使用AREA_AVERAGED方法执行此操作,但它比Chris Campbell在他的“Perils of Image.getScaledInstance()”文章中提出的原始增量缩减要慢得多。
请原谅这里的自我推销,但在图像扩展到名为imgscalr的库中时,我推出了一些“原生Java最佳实践”。
它在Apache 2许可下可用,源代码全部在GitHub上;该库的目标是在原生Java中实现图像缩放(1类,5种静态方法),并确保获得最佳效果(这是您最初想要的),最快的结果(在大图像之间缩放时效果很好) )或两者之间的平衡,让图书馆决定使用哪一个。
我只是想要一个可以“调整我的图像并让我的方式”的lib,并且在阅读了所有这些帖子几天之后我解决了痛点(我自己也是这样),只是回过头来分享为其他任何人提供帮助。
答案 3 :(得分:0)
Coobird有正确的想法。我也会尝试RenderingHints.VALUE_INTERPOLATION_BILINEAR
插值,看看它是否更好看。但是,当升级时,Bicubic的效果会更好。为了在降尺度时获得最佳结果,应该在几个步骤中缩小。先将分辨率减半,然后再减半等,直到接近所需的分辨率(即你不能减半或图像变得太小)。最后一步是缩小到所需的分辨率。
例如,假设您的输入图片 800x600 ,并且您希望缩小到 160x120 :