java 以编程方式减小 JPEG 文件大小

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6830478/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 17:27:44  来源:igfitidea点击:

Programmatically Reducing JPEG file size

javagraphics2djpeg

提问by Joeblackdev

Apologies for any ignorance, but I have never worked with jpeg images (let alone any types of images) in Java before.

对任何无知表示歉意,但我以前从未在 Java 中使用过 jpeg 图像(更不用说任何类型的图像)了。

Supposing I want to send a jpeg image from a web service to a client. Is there any way that I can reduce the jpeg file size by manipulating the colour profile of the image in some way?

假设我想从 Web 服务向客户端发送 jpeg 图像。有什么方法可以通过以某种方式操纵图像的颜色配置文件来减小 jpeg 文件大小?

I have already been able to reduce the image size by scaling it using a neat tool for BufferedImages called imgscalr. See here.

我已经能够通过使用名为imgscalr. 见这里

I would also like a jpeg that has less colours than a high quality jpeg image. For example, I would like to be able to use 8bit colour in my jpeg instead of say 16bit colour.

我还想要一个颜色比高质量 jpeg 图像少的 jpeg。例如,我希望能够在我的 jpeg 中使用 8 位颜色而不是 16 位颜色。

What exactly would I need to change if I have a BufferedImage from Java's 2D package?

如果我有一个来自 Java 2D 包的 BufferedImage,我到底需要改变什么?

采纳答案by Lev Khomich

Another way to reduce image size is to change compression level. You can do that using ImageWriter.

减小图像大小的另一种方法是更改​​压缩级别。您可以使用 ImageWriter 来做到这一点。

    ImageWriter writer = null;
    Iterator<ImageWriter> iwi = ImageIO.getImageWritersByFormatName("jpg");
    if (!iwi.hasNext())
        return;
    writer = (ImageWriter) iwi.next();
    ImageWriteParam iwp = writer.getDefaultWriteParam();
    iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT) ;
    iwp.setCompressionQuality(compressionQuality);
    writer.setOutput(...);
    writer.write(null, image, iwp);

回答by Maurício Linhares

Two of the possible solutions are downscaling the image, here's how you'd do it:

两种可能的解决方案是缩小图像,这是您的操作方法:

BufferedImage original = //your image here
scaled = original.getScaledInstance(finalWidth, finalHeight, Image.SCALE_SMOOTH); // scale the image to a smaller one

BufferedImage result = new BufferedImage(finalWidth, finalHeight, original.getType());
Graphics2D g = result.createGraphics();     

g.drawImage(scaled, 0, 0, null); //draw the smaller image
g.dispose();

Obviously, you have to calculate the scaled width and height so the image stays by the same aspect ratio.

显然,您必须计算缩放后的宽度和高度,以便图像保持相同的纵横比。

Once you have drawn it smaller, you can now turn this image into a JPEG file:

将其绘制得更小后,您现在可以将此图像转换为 JPEG 文件:

BufferedImage image = // this is the final scaled down image

JPEGImageEncoder jpegEncoder = JPEGCodec.createJPEGEncoder(output);
JPEGEncodeParam jpegEncodeParam = jpegEncoder.getDefaultJPEGEncodeParam(image);

jpegEncodeParam.setDensityUnit(JPEGEncodeParam.DENSITY_UNIT_DOTS_INCH);
jpegEncodeParam.setXDensity(92);
jpegEncodeParam.setYDensity(92);

jpegEncodeParam.setQuality( 0.8F , false);
jpegEncoder.encode(image, jpegEncodeParam);

These classes are from the JAIpackage (more exactly com.sun.image.codec.jpeg) and the JVM might complain that they should not be used directly, but you can ignore that.

这些类来自JAI包(更准确地说是com.sun.image.codec.jpeg),JVM 可能会抱怨不应直接使用它们,但您可以忽略这一点。

You can possibly download JAI from here, if it does not work I have github mirrors setup for the two libraries, JAI coreand JAI ImageIO.

您可以从这里下载 JAI ,如果它不起作用,我为两个库JAI 核心JAI ImageIO设置了 github 镜像。

回答by Thorbj?rn Ravn Andersen

The easiest way to do this is to decompress the byte stream into a Java Image, optionally resize it (which makes it smaller) and then regenerate a JPEG image from this with the desired quality setting.

最简单的方法是将字节流解压缩为 Java 图像,可选择调整其大小(使其更小),然后使用所需的质量设置从中重新生成 JPEG 图像。

This new image is then what is sent to the client.

这个新图像然后被发送到客户端。

回答by Thomas

Have a look at the ImageIOclass. As for reducing file size: since the image would already be a JPEG the only things you could do is reduce the quality or the image size.

看看ImageIO班级。至于减小文件大小:由于图像已经是 JPEG,因此您唯一能做的就是降低质量或图像大小。

Another thing to keep in mind: if the image is a CMYK jpeg it might be bigger. Unfortunately ImageIOcan't handle those, but you can try JAI ImageIOto convert from CMYK to RGB (which should be much smaller).

要记住的另一件事:如果图像是 CMYK jpeg,它可能会更大。不幸的是ImageIO无法处理这些,但您可以尝试JAI ImageIO从 CMYK 转换为 RGB(应该小得多)。