使用Java JAI缩放图像 [英] Scaling images with Java JAI

查看:760
本文介绍了使用Java JAI缩放图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须使用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));

//缩放图像时的质量相关提示
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));

返回JAI.create(scale,scaleParams,scalingHints);
}

不幸的是,这导致非常糟糕的结果,特别是因为我经常需要扩展比例因子小于0.5的图像...



任何建议?

解决方案

我猜您试图将较大的图像缩放到缩略图大小或从原始图像到缩放图像的某些大小差异?



If-so,这个主题实际上是2007年来自Java2D的Chris Campbell所说的(我不希望你知道这一点,只是指出这是一个常见的问题),因为新的Java2D缩放方法(RenderingHints.VALUE_INTERPOLATION_ *)没有提供相同的当时已弃用的 Image.getScaledInstance(SCALE_AREA_AVERAGING或SCALE_SMOOTH)方法。



事实证明,旧的Java 1.1中的SCALE_AREA_AVERAGING或SCALE_SMOOTH方法Image.getScaledInstanc e方法是一个相当昂贵的多步操作,它在后台做了大量的工作来生成漂亮的图像。



Chris指出新的并且使用Java2D获得相同结果的正确方法是一次又一次地缩放图像,直到达到所需的图像大小,优选使用更高质量的比例,如RenderHints.VALUE_INTERPOLATION_BICUBIC或BILINEAR。



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



我实际上去了几个月前在编写图像托管服务时寻找这个答案,并对如何在Java中制作漂亮的缩略图这一简单问题感到惊讶。我终于创建了一个小型Java库(Apache 2,开源),它使用最佳实践(包括增量方法)实现了3种不同的Java图像缩放方法克里斯建议。



该库被称为 imgscalr 。你可以下载和使用它简单如下:

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

有更多选项可供设置和使用(例如缩放的质量或速度)但不包括这个盒子有智能默认设置,可以为你制作漂亮的缩放图像,这样你就不必担心更多,如果你不想这样做。该库还大力处理并避免任何非绝对必要的Object分配,并在不需要时立即处理BufferedImage实例 - 它应该是代码作为长期运行的服务器应用程序的一部分,所以这是关键。



我已经制作了一些图书馆的版本,如果您只是想撕掉好东西并自己做一些事情,去吧。这一切都在 GitHub 上,并没有一个是绝密,只是为了让人们的生活更轻松。



希望有所帮助。


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?

解决方案

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.

这篇关于使用Java JAI缩放图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆