在服务器上缩放和缩小图像

Scaling and size-reducing image on a server

我需要缩小 JPG 图像以使其适合 1024x640 矩形并保存它,使其大小不超过 20 kB。通过一些谷歌搜索,我设法做到了这两点。对于缩放,我使用

private static BufferedImage scale(BufferedImage input, int width, int height) {
    final int type = input.getTransparency() == Transparency.OPAQUE ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
    final BufferedImage result = new BufferedImage(width, height, type);
    final Graphics2D g2 = result.createGraphics();
    g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
    g2.drawImage(input, 0, 0, width, height, null);
    g2.dispose();
    return result;
}

为了缩小尺寸,我使用 ImageWriterJPEGImageWriteParam 并以降低的质量重复,直到文件大小低于限制。

它在我的机器上都运行得很好,但在测试服务器上,它的表现很糟糕:

original file size:    174548
scaled down file size:  16995 - on my machine
                       228218 - on the server

所以缩小后的图片比原图大,画质也很差。

虽然它可能与 headless java problem 有关,但 java 安装不是无头的(我从来没有得到 HeadlessException):

java -version
openjdk version "1.8.0_222"
OpenJDK Runtime Environment (build 1.8.0_222-8u222-b10-1ubuntu1~16.04.1-b10)
OpenJDK 64-Bit Server VM (build 25.222-b10, mixed mode)

知道发生了什么吗?

我们使用 ImageMagick 来调整图像大小和重新格式化。它可以给你灵活性。我们设法较早地使用它来满足与您类似的需求。

ImageMagick 利用多个计算线程来提高性能,并且可以读取、处理或写入百万、千兆或万亿像素的图像大小。

它是免费的开源的。您可以参考官方网站了解更多详情:https://imagemagick.org/index.php

示例程序如下所示:

ConvertCmd cmd = new ConvertCmd();

// create the operation, add images and operators/options
IMOperation op = new IMOperation();
op.addImage("source_picture.jpg"); // source file
op.resize(800,600);
// of op.resize(800); // and height calculate automatically
op.addImage("resized_picture.jpg"); // destination file file

// execute the operation
cmd.run(op);

检查相关的Whosebug线程Image magick java

希望对您有所帮助!

问题是使用 Graphics2D 完成的大小调整。不知道为什么它做了它所做的,但是在用 java-image-scaling 替换它之后,问题就消失了。

很可能有更好的库,但对于当前的需求来说,这个已经足够好了。