为什么这个图像在Java中按比例缩小后看起来这么糟糕?
这是原始图像: http://rank.my/public/images/uploaded /orig-4193395691714613396.png
这里它被缩小到300x225:
http://rank.my/public/images/uploaded/norm-4193395691714613396.png
这里它被缩小到150x112:
http://rank.my/public/images/uploaded/small-4193395691714613396.png
如您所见,300x225 看起来很糟糕,150x112 看起来很糟糕。这是我用来缩小图像的代码:
private static BufferedImage createResizedCopy(final BufferedImage source, final int destWidth,
final int destHeight) {
final BufferedImage resized = new BufferedImage(destWidth, destHeight, source.getType());
final Graphics2D bg = resized.createGraphics();
bg.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
bg.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
bg.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
final float sx = (float) destWidth / source.getWidth();
final float sy = (float) destHeight / source.getHeight();
bg.scale(sx, sy);
bg.drawImage(source, 0, 0, null);
bg.dispose();
return resized;
}
我在这里做错了什么?图像缩放不必特别快,质量绝对优先于速度。我使用了错误的技术吗?
Here is the original image: http://rank.my/public/images/uploaded/orig-4193395691714613396.png
And here it is scaled down to 300x225:
http://rank.my/public/images/uploaded/norm-4193395691714613396.png
And here it is scaled down to 150x112:
http://rank.my/public/images/uploaded/small-4193395691714613396.png
As you can see, 300x225 looks pretty bad, and 150x112 looks awful. Here is the code I'm using to scale down the image:
private static BufferedImage createResizedCopy(final BufferedImage source, final int destWidth,
final int destHeight) {
final BufferedImage resized = new BufferedImage(destWidth, destHeight, source.getType());
final Graphics2D bg = resized.createGraphics();
bg.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
bg.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
bg.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
final float sx = (float) destWidth / source.getWidth();
final float sy = (float) destHeight / source.getHeight();
bg.scale(sx, sy);
bg.drawImage(source, 0, 0, null);
bg.dispose();
return resized;
}
What am I doing wrong here? The image scaling doesn't have to be especially fast, quality is definitely a priority over speed. Am I using the wrong technique?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
解决缩小问题的方法有3种。首先是分多个步骤进行,每个步骤的减少量不超过 75%。第二种是在调整大小之前对图像进行模糊处理;它收缩得越多,你就越需要模糊。第三种方法是使用一种方法,该方法使用比朴素双线性或双三次插值方法所使用的 2x2 到 4x4 像素块更多的像素块进行过滤。随着收缩因子变大,过滤器使用的像素块也应该变大,否则您会得到锯齿伪像,正如您在此处看到的那样。
There are three ways to fix the downscaling problem. First is to do it in multiple steps, with no more than a 75% reduction in each step. The second is to blur the image before resizing; the more it shrinks, the more you'll have to blur. The third way is to use a method that filters using more than the 2x2 to 4x4 pixel blocks used by a naive bilinear or bicubic interpolation method. As the shrink factor grows larger, so should the pixel block used by the filter, otherwise you get aliasing artifacts as you've seen here.
我从未使用过这些库,所以我觉得没有资格回答,但我忍不住传递这些我发现我认为可能有用的链接。希望这会有所帮助。
http://today.java .net/pub/a/today/2007/04/03/perils-of-image-getscaledinstance.html
http://www.componenthouse.com/article-20
I've never used these libraries so I feel unqualified to answer, but I can't help but pass along these links I found that I think may be useful. Hopefully this will help.
http://today.java.net/pub/a/today/2007/04/03/perils-of-image-getscaledinstance.html
http://www.componenthouse.com/article-20
JAI 非常令人沮丧。我仍然想知道为什么,无论你做什么设置,它都无法与 ImageMagick 的速度、质量和简单性相匹配。我更喜欢尽可能使用 ImageMagick。
下面的代码为我提供了图像缩放的最佳结果。请注意,我使用了
RenderingHints.VALUE_RENDER_QUALITY
和SubsampleAverage
,没有RenderingHints.VALUE_INTERPOLATION_BICUBIC
。我将 JAI 处理封装在一个小块中,并始终使用它来缩小规模。当您放大时,相同的代码不会给出良好的结果 - 不同的设置适用于此。我没有尝试过使用 PNG,我使用的是 JPEG。
希望这有帮助
另外,对我有帮助的文章是。
http://forums.sun.com/thread.jspa?threadID=5332078看起来 Oracle 收购后他们已经洗掉了论坛帖子。这是一次关于 JAI 性能和质量的非同寻常的讨论。我仍然把它加了书签。(上面的链接来自我的书签,如果您发现请编辑它们他们死了)
JAI is pretty frustrating. I still wonder why, no matter what settings you do, it never matches the speed, quality and simplicity of ImageMagick. I prefer to use ImageMagick wherever I can.
The code below is what gives me best result for image scaling. Please note that I have used
RenderingHints.VALUE_RENDER_QUALITY
andSubsampleAverage
and notRenderingHints.VALUE_INTERPOLATION_BICUBIC
.I have wrapped up JAI processing in a small block and always use it to scale down. The same code does not give good result when you scale-up -- a different setting applies for that. I have not tried with PNG, JPEG is what I worked with.
Hope this helps
Also, the articles that helped me are.
http://forums.sun.com/thread.jspa?threadID=5332078Looks like after Oracle acquisition they have washed away the forum posts. This was an extra-ordinary discussion over JAI performance and quality. I still had it bookmarked.(The links above are from my bookmark, edit them if you find they are dead)