以编程方式缩小JPEG文件大小
为任何无知道歉,但我以前从未使用Java中的jpeg图像(更不用说任何类型的图像)了。
假设我想从Web服务向客户端发送jpeg图像。 有什么方法可以通过某种方式操纵图像的颜色配置文件来减少jpeg文件的大小?
我已经能够通过使用称为imgscalr
BufferedImages的简洁工具来缩小图像大小。 看到这里 。
我还想要一个颜色比高质量jpeg图像少的jpeg。 例如,我希望能够在我的jpeg中使用8位颜色而不是16位颜色。
如果我有来自Java的2D包的BufferedImage,我到底需要改变什么呢?
减小图像大小的另一种方法是更改压缩级别。 你可以使用ImageWriter来做到这一点。
ImageWriter writer = null; Iterator 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);
最简单的方法是将字节流解压缩为Java Image,可选择调整其大小(使其更小),然后使用所需的质量设置从中重新生成JPEG图像。
然后,这个新图像将发送给客户端。
看看ImageIO
类。 至于减小文件大小:由于图像已经是JPEG,因此您可以做的唯一事情就是降低质量或图像大小。
要记住的另一件事是:如果图像是CMYK jpeg,它可能会更大。 不幸的是, ImageIO
无法处理这些问题,但您可以尝试使用JAI ImageIO
将CMYK转换为RGB(应该小得多)。
两种可能的解决方案是降低图像尺寸,这是你如何做到的:
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,如果它不起作用我有两个库, JAI核心和JAI ImageIO的 github镜像设置。