您拥有的图像将以最高质量设置(“
100%”或
1.0以ImageIO的形式)压缩。JPEG压缩在如此高的设置下不是很有效,因此比平时大很多。使用
ImageIO.write(...,"JPEG", ...)默认质量设置时。此默认值是
0.75(此值的确切含义虽然与编码器有关,但并不完全是科学依据),因此质量较低,因此文件较小。
(另一个可能导致原始图像和重新压缩后的图像之间的文件大小显着减小的原因是删除了元数据。使用进行读取
ImageIO.read(file)时,实际上是在剥离JPEG文件中的任何元数据,例如XMP,Exif或ICC配置文件。在极端情况下(是的,我在这里主要是在谈论Photoshop
;-),此元数据可能比图像数据本身占用更多的空间(即,可能有数百万字节的元数据)。但是,文件不是这种情况。)
从第二次重新压缩(从
byte[]到最终输出文件)可以看到,输出仅略小于输入。这是因为两种情况下的质量设置(未指定,因此仍使用默认设置)是相同的(此外,在此步骤中任何元数据也会丢失,因此不会增加文件大小)。较小的差异可能是由于JPEG解压缩/重新压缩中的一些小损失(舍入误差等)引起的。
尽管有点违反直觉,但是在重新压缩JPEG时,总是通过相同质量设置(使用完全相同的质量)的重新压缩来实现最小的数据丢失(根据与原始图像的变化,而不是文件大小的变化)表格实际上应该是无损的,但仍会像原始表格那样产生较小的舍入误差。增加质量设置将使文件输出更大,但是质量实际上会降低。
确保不丢失任何数据或图像质量的唯一方法是,首先不要解码/编码图像,而只是逐字节复制文件,例如:
File in = ...;File out = ...;InputStream input = new FileInputStream(in);try { OutputStream output = new FileOutputStream(out); try { copy(input, output); } finally { output.close(); }}finally { input.close();}和复制方法:
public void copy(final InputStream in, final OutputStream out) { byte[] buffer = new byte[1024]; int count; while ((count = in.read(buffer)) != -1) { out.write(buffer, 0, count); } // Flush out stream, to write any remaining buffered data out.flush();}

![使用BufferedImage和ImageIO将图像转换为byte []后,图像尺寸减小 使用BufferedImage和ImageIO将图像转换为byte []后,图像尺寸减小](http://www.mshxw.com/aiimages/31/428826.png)
