编程减小JPEG文件大小

10

很抱歉,我之前从未在Java中使用过JPEG图像(更不用说任何类型的图像)。

假设我想从Web服务向客户端发送JPEG图像。有没有办法通过某种方式操纵图像的色彩配置文件来减小JPEG文件的大小?

我已经能够使用名为imgscalr的BufferedImages工具缩放图像以减小图像的大小。请参阅此处

我也想要一张比高质量JPEG图像颜色更少的JPEG图像,例如,我想使用8位色而不是16位色。

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

4个回答

5

减小图片大小的另一种方法是改变压缩级别。您可以使用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);

嗨,将JPEG的压缩率更改会对视觉产生什么影响?谢谢。 - Joeblackdev
1
请查看这篇文章:http://www.codinghorror.com/blog/2006/07/a-comparison-of-jpeg-compression-levels-and-recompression.html - Lev Khomich
我会仔细查看,感谢提供链接。不过我在想是否有一种方法(使用该链接中的图像),可以在JPEG中使用更少的颜色?例如,使用8位颜色而不是16位颜色?谢谢。 - Joeblackdev
3
这是答案。JPEG仅适用于完整的彩色调色板。如果您想使用另一种格式(如png或gif),则可以选择缩短调色板。 - Rekin
@Rekin,你有没有任何缩短PNG图像调色板的示例? - Joeblackdev
显示剩余2条评论

1

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

然后将此新图像发送给客户端。


谢谢您提供的信息,但这正是我目前所拥有的。我使用一个名为imgscalr的工具,在将JPEG图像发送到客户端之前调整其大小。然而,我还想更新JPEG的颜色配置文件以减少其中的颜色。所谓的“减少”,是指使用更少的颜色。我不确定这个术语的叫法... - Joeblackdev

1

看一下ImageIO类。至于减小文件大小:由于图像已经是JPEG格式,您可以做的唯一事情就是降低质量或图像大小。

还有一件事要记住:如果图像是CMYK JPEG格式,则可能会更大。不幸的是,ImageIO无法处理这些格式,但您可以尝试使用JAI ImageIO将其从CMYK转换为RGB(应该会更小)。


1

两种可能的解决方案之一是缩小图像,以下是如何操作:

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();

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

一旦您将其缩小,现在可以将此图像转换为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);

这些类来自于JAI包(更确切地说是com.sun.image.codec.jpeg),JVM 可能会抱怨不应该直接使用它们,但你可以忽略它。
你可以在这里下载 JAI,如果无法下载,我已经为这两个库设置了 GitHub 镜像:JAI coreJAI ImageIO

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接