使用 Java JAI 缩放图像

发布于 2024-10-03 10:05:45 字数 1262 浏览 8 评论 0原文

我必须使用 Java JAI 缩放图像。目前,我使用以下代码:

private static RenderedOp scale(RenderedOp image, float scale) {
    ParameterBlock scaleParams = new ParameterBlock();
    scaleParams.addSource(image);
    scaleParams.add(scale).add(scale).add(0.0f).add(0.0f);
    scaleParams.add(Interpolation.getInstance(Interpolation.INTERP_BICUBIC_2));

    // Quality related hints when scaling the image
    RenderingHints scalingHints = new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
    scalingHints.put(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
    scalingHints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    scalingHints.put(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
    scalingHints.put(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
    scalingHints.put(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
    scalingHints.put(JAI.KEY_BORDER_EXTENDER, BorderExtender.createInstance(BorderExtender.BORDER_COPY));

    return JAI.create("scale", scaleParams, scalingHints);
}

不幸的是,这会导致非常糟糕的结果,特别是因为我经常必须以小于 0.5 的比例因子缩放图像...

有什么建议吗?

I have to scale an image with Java JAI. At the time now, I use the following code:

private static RenderedOp scale(RenderedOp image, float scale) {
    ParameterBlock scaleParams = new ParameterBlock();
    scaleParams.addSource(image);
    scaleParams.add(scale).add(scale).add(0.0f).add(0.0f);
    scaleParams.add(Interpolation.getInstance(Interpolation.INTERP_BICUBIC_2));

    // Quality related hints when scaling the image
    RenderingHints scalingHints = new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
    scalingHints.put(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
    scalingHints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    scalingHints.put(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
    scalingHints.put(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
    scalingHints.put(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
    scalingHints.put(JAI.KEY_BORDER_EXTENDER, BorderExtender.createInstance(BorderExtender.BORDER_COPY));

    return JAI.create("scale", scaleParams, scalingHints);
}

Unfortunately, this leads to very bad results, especially because I often have to scale images with a scale factor less than 0.5...

Any advice?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

倾城花音 2024-10-10 10:05:45

我猜您正在尝试将较大的图像缩小到缩略图大小,或者原始图像与缩放图像之间存在同样大的差异?

如果是这样,这个主题实际上是由 Java2D 的 Chris Campbell 在 2007 年提出的(我并不指望您知道这一点,只是指出这是一个常见问题),因为新的 Java2D 缩放方法 (RenderingHints.VALUE_INTERPOLATION_*) 没有提供与当时已弃用的 Image.getScaledInstance(SCALE_AREA_AVERAGING 或 SCALE_SMOOTH) 方法。

事实证明,旧 Java 1.1 Image.getScaledInstance 方法中的 SCALE_AREA_AVERAGING 或 SCALE_SMOOTH 方法是相当昂贵的多步骤操作,需要在后台执行大量工作才能生成漂亮的图像。

Chris 指出,使用 Java2D 获得相同结果的新“正确”方法是不断将图像缩放一半的增量过程,直到达到所需的图像大小,最好使用更高质量的缩放,例如RenderHints.VALUE_INTERPOLATION_BICUBIC 或 BILINEAR。

结果与人们想要的原始 Image.getScaledInstance 方法几乎相同。

实际上,几个月前,我在编写图像托管服务时就开始寻找这个答案,并对“如何用 Java 制作漂亮的缩略图?”这个简单问题的复杂性感到惊讶。成为。

我最终创建了一个小型 Java 库(Apache 2,开源),它使用“最佳实践”(包括 Chris 建议的增量方法)在 Java 中实现了 3 种不同的图像缩放方法。

该库名为 imgscalr。您可以下载并使用它,就像这样简单:

BufferedImage thumbnail = Scalr.resize(srcImage, 150);

有更多选项可供设置和使用(例如缩放的质量或速度),但开箱即用的所有内容都有智能默认值,可以为您制作漂亮的缩放图像,以便您如果您不想的话,不必担心更多。该库还做出了很大的努力来处理和避免任何不是绝对必要的对象分配,并在不需要时立即处理 BufferedImage 实例——它的目的是作为长期运行的服务器应用程序的一部分,所以这是批判的。

我已经发布了该库的几个版本,如果您只想撕掉“好东西”并自己做一些事情,那就去做吧。这一切都在 GitHub 上,而且都不是绝密,只是为了让人们的生活更轻松。

希望有帮助。

I am guessing you are trying to scale a larger image down to a thumbnail size or some equally large difference from original to scaled image?

If-so, this topic was actually address by Chris Campbell from the Java2D back in 2007 (I am not expecting you knew this, just pointing out that it's a common question) because the new Java2D scaling approaches (RenderingHints.VALUE_INTERPOLATION_*) did not provide an equivalent to the then-deprecated Image.getScaledInstance(SCALE_AREA_AVERAGING or SCALE_SMOOTH) approach.

As it turns out, the SCALE_AREA_AVERAGING or SCALE_SMOOTH approaches in the old Java 1.1 Image.getScaledInstance approach was a fairly expensive, multi-step operation that was doing a lot of work in the background to generate that nice-looking image.

Chris pointed out that the new and "correct" way, using Java2D, to get this same result is an incremental process of scaling the image in-half over and over until the desired image size is reached, preferably using a higher-quality scale like RenderHints.VALUE_INTERPOLATION_BICUBIC or BILINEAR.

The result comes out almost identical to the original Image.getScaledInstance approach that folks want.

I actually went hunting for this answer a few months ago while writing an image-hosting service and was surprised at how complicated the simple question of "How do I make a nice looking thumbnail in Java?" became.

I eventually create a small Java library (Apache 2, open sourced) that implements 3 different approaches to image scaling in Java using "best practices" including the incremental approach that Chris suggested.

The library is called imgscalr. You can download and use it as simple as:

BufferedImage thumbnail = Scalr.resize(srcImage, 150);

There are more options to set and use (e.g. the Quality or Speed of the scaling) but out of the box there are intelligent defaults for everything to make a nice looking scaled image for you so you don't have to worry about more if you don't want to. The library also makes a strong effort to dispose of and avoid any Object allocation that isn't absolutely necessary and dispose of BufferedImage instances immediately if not needed -- it is intended to be code as part of a long-running server app so this was critical.

I've made a few releases of the library already, and if you'd rather just rip out the "good stuff" and do something with it yourself, go for it. It is all on GitHub and none of it is top secret, just an attempt to make people's lives easier.

Hope that helps.

柏拉图鍀咏恒 2024-10-10 10:05:45

我使用 Thumbnailator 获得了良好的结果。我不知道 JAI.KEY_BORDER_EXTENDER 应该做什么,但我猜支持其余功能(抗锯齿、抖动等)。
我用它来生成相当大的黑白图像的灰度缩略图

I've obtained good results with Thumbnailator. I don't know what JAI.KEY_BORDER_EXTENDER is supposed to do, but I guess the rest of the functionality (antialiasing, dithering, etc) is supported.
I used it to generate grayscale thumbnails of quite big black and white images

暮色兮凉城 2024-10-10 10:05:45

如果你幸运的话,你只有 Black & 。白色图像,然后您可以使用非常快速且高质量的操作: SubsampleBinaryToGray

If you are lucky and you have only Black & White images, then you can use very fast and good quality operation: SubsampleBinaryToGray

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文