我们有一个使用servlet来调整图像大小的图片库——我们需要良好的性能和体面的质量,但是我们就是做不到。而且,很遗憾,我们只有java 1.4,这让我们几乎没有外部图像库(我找到的几乎所有东西都是java 1.5+), java图像处理真的不好。
如果我使用这个:
private static BufferedImage scaleImage(BufferedImage orig, int type, int w, int h) {
BufferedImage tmp = new BufferedImage(w, h, type);
Graphics2D g2 = tmp.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.drawImage(orig, 0, 0, w, h, null);
g2.dispose();
return tmp;
}
的结果几乎每次都一样(而且看起来很糟糕)或者非常慢,这取决于所选择的提示。我几乎阅读了所有关于在java中调整图像大小的文章(包括这篇),但它没有帮助。
你有什么想法吗?java 1.4有没有速度快、质量好的外部库?有什么算法能得到好的结果吗?
您可以尝试像JMagick这样的Image Magick包装器
Izk,考虑到您的需求,我同意Thomas的观点,您(很可能)需要依赖外部/本机库。
如果你没有明确提到性能,我会建议使用BICUBIC插值和Chris Campbell的增量缩放算法。imgscalr库实现了所有这些,但它需要Java 5(使用枚举)。也就是说,您可以轻松地将代码复制到Java 1.4兼容的实现中。
去看看Scalr类,滚动到最底部,复制最后两个方法。如果你想让它在Java中实现,这就是你需要完成95%的工作。
但是,如果到目前为止您发现java伸缩性能是不可接受的,那么该实现将无法帮助您。你需要考虑使用像ImageMagick这样的本地库。
幸运的是,ImageMagick有两个流行的Java绑定,如果JMagick API不允许你处理InputStreams,你可以看看im4java,它是ImageMagick命令行版本的直接包装器。我挖掘了源代码,它看起来像核心ImageCommand类,用于包装"命令"发送到命令行,直到允许您在执行操作时将BufferedImage实例作为"images"对象参数传递。
如果是这种情况,你可以使用ImageIO.read(InputStream)将图像数据读取到BufferedImage中,然后将其发送给ImageMagick,使用im4java API进行处理。