图像调整质量 (Java) [已关闭]

2022-09-03 16:50:09

我有一个开源应用程序,可以将照片上传到Facebook。为了节省带宽,照片会在上传前自动调整大小(Facebook 施加了最大大小限制)。有些人抱怨照片质量,实际上你可以看到差异(请参阅此问题以获取一些演示图像)。

所以我的问题是,在不损失质量的情况下,或者至少以最小的质量损失/伪影在Java中缩小图像(即照片)的“最佳”方法是什么?

您可以看到我在这里拥有的当前代码(通过此页面调整代码大小)。


答案 1

Phil,我不知道你最终选择了哪种解决方案,但是如果你:

  • 避免使用 JDK 不能很好地支持的 BufferedImage 类型。
  • 使用增量扩展
  • 使用增量扩展时坚持使用双三次

我已经用这些方法做了相当多的测试,增量缩放以及坚持支持良好的图像类型是关键 - 我看到亚历山大提到他仍然没有得到好运气,这是一个令人沮丧的事情。

大约6个月前,我发布了imgscalr库(Apache 2),以解决“我想要这个图像的好看的缩放副本,现在就做!”的问题,在阅读了SO上的10个类似问题之后。

标准用法如下所示:

BufferedImage img = ImageIO.read(...); // load image
BufferedImage scaledImg = Scalr.resize(img, 640);

第二个参数是imgscalr将用于缩放图像的边界宽度和高度 - 即使您在无效维度中传递,也保持其比例正确 - 有许多更详细的方法,但这是最简单的用法。

您想要的用例,例如,如果Facebook将图像限制为800x600像素,将如下所示:

BufferedImage img = ImageIO.read(...); // load image
BufferedImage scaledImg = Scalr.resize(img, Method.QUALITY, 800, 600);

这将确保图像保持在最佳支持的图像类型中,并使用Java可以聚集的最高质量方法进行缩放。

在我自己的高分辨率测试中,我没有注意到使用此库/这些方法缩放图像的任何巨大差异,除非您的图像被ImageIO加载程序放入支持不佳的图像类型中 - 例如,GIF经常发生这种情况。如果你像这样离开它们,不把它们从那些支持不足的类型中解救出来,它最终会看起来非常犹豫不决和可怕。

这样做的原因是,Java2D团队实际上为JDK可以处理的所有不同类型的BufferedImages提供了不同的硬件加速管道 - 这些不太常见的图像类型的子集都回退到在Java2D的掩护下使用相同的软件渲染管道,导致图像看起来很差,有时看起来完全不正确。这是一个这样的PIA来解释和尝试弄清楚,我只是将这个逻辑直接写入了图书馆。

两种最受支持的类型是BufferedImage.TYPE_INT_RGB,如果您好奇,_ARGB。


答案 2

我已经尝试了一切 - 包括这里的技巧,我只能说你最好在任何界面上使用ImageMagick。Java的映像库在这方面并不达标。您需要支持如此多的格式和算法才能正确使用。


推荐