使用Java JAI缩放图像

Bas*_*sil 7 java scaling image 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));

    // 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);
}
Run Code Online (Sandbox Code Playgroud)

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

有什么建议?

Riy*_*lla 15

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

如果是这样的话,这个主题实际上是由2007年的Java2D的Chris Campbell解决的(我不希望你知道这一点,只是指出这是一个常见的问题),因为新的Java2D扩展方法(RenderingHints.VALUE_INTERPOLATION_*)没有提供与当时不推荐使用的Image.getScaledInstance(SCALE_AREA_AVERAGING或SCALE_SMOOTH)方法的等效方法.

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

克里斯指出,使用Java2D获得同样结果的新的"正确"方法是一次又一次地缩放图像,直到达到所需的图像大小,最好使用更高质量的比例. RenderHints.VALUE_INTERPOLATION_BICUBIC或BILINEAR.

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

几个月前,我在编写图像托管服务时实际上是在寻找这个答案,并对"如何在Java中制作漂亮的缩略图?"这个简单问题感到惊讶.成了.

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

该库名为imgscalr.您可以像下载一样简单地下载和使用它:

BufferedImage thumbnail = Scalr.resize(srcImage, 150);
Run Code Online (Sandbox Code Playgroud)

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

我已经发布了一些库的版本,如果你只是想撕掉"好东西"并自己做一些事情,那就去吧.这一切都在GitHub上,没有一个是绝密的,只是为了让人们的生活更轻松.

希望有所帮助.