Java图像大小调整 - 最近邻插值

4

我正在尝试使用Java调整图像大小,并且需要获得与Photoshop最近邻居(保留硬边)重新调整大小时发生的确切效果。

问题在于,我从未获得完全相同的效果...

我尝试了以下方法:

1)使用mortennobel lib的java-image-scale

resampleOp.setFilter(ResampleFilters.getBoxFilter());

这个方法的效果很好,但是会留下一些图像伪影,而Photoshop处理时没有这种情况。
2)TwelveMonkeys图像处理库。(这里是GitHub链接)PointFilter会完全破坏内部渐变,Box filter与mortennobel getBoxFilter做的事情相同。
3)AWT AffineTransform,这是最糟糕的一个,调整大小完全不真实。
现在我很困惑,Photoshop的最近邻插值缩放是否与其名称所表示的含义不同,还是所有其他库都做错了(在第二种情况下,哪个库会做得正确?)
以下是Photoshop生成的图片: enter image description here enter image description here 以下是由mortennobel库的get BoxFilter生成的图像: enter image description here 我稍微放大了一些图片,以便您可以看到细节,实际上它们更小。非常感谢任何帮助 :) 我真的被卡住了。

mortennobel库使用盒式滤波器,因此不符合您的要求——最近邻。您考虑过自己编写代码吗?在没有任何过滤的情况下迭代原始图像像素并不难。 - Jongware
嗯..我以为盒式滤波和最近邻居是一样的。嗯,我考虑过了,但我认为这可能会很慢,另外,应该有一个库可以做到吧?不要使用花哨的滤镜,只需使用简单的即可,这就是我想要的全部。我觉得 Photoshop 所做的还有另一个名字,如果我知道它,我就能找到正确的库。 - Avetis Zakharyan
2
你可能需要解释一下使用RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR的结果与你想要实现的目标有多大差异(也可以参见https://today.java.net/pub/a/today/2007/04/03/perils-of-image-getscaledinstance.html#creating-scaled-instances)。 - Marco13
@Marco13,实际上那解决了问题!!!谢谢!你想要发布一个示例代码作为答案,这样我就可以点赞吗?或者如果你愿意的话,我也可以自己做 :) - Avetis Zakharyan
我只能创建一个非常基于链接站点代码的片段,并猜测有关细节以帮助解决您的问题。您可以回答自己的问题(否则我会尝试创建一个合适的答案,但我认为您的答案会更切题)。 - Marco13
奇怪...使用TwelveMonkeys/method 2的ResampleOpPointFilter应该产生与AffineTransformOpVALUE_INTERPOLATION_NEAREST_NEIGHBOR完全相同的结果(因为它在内部使用它)。如果这不是,那么应该被视为一个错误。哦不!;-) - Harald K
1个回答

2

非常感谢Marco13指出这一点!显然,mortennobel lib不支持最近邻插值, 而是可以使用RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR渲染提示来使用AWT的Graphics2D进行操作。 以下是我使用的代码片段,它产生了与Photoshop完全相同的图像。

destinationBufferedImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = destinationBufferedImage.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
g2.drawImage(sourceBufferedImage, 0, 0, newWidth, newHeight, null);
g2.dispose();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接