String dirName=System.getProperty("user.home") + "/deleteme";
ByteArrayOutputStream byteArrayOutputStream=new ByteArrayOutputStream(1000);
BufferedImage bufferedImage=ImageIO.read(new File(dirName,"a.jpg"));
ImageIO.write(bufferedImage, "jpg", byteArrayOutputStream);
byteArrayOutputStream.flush();
byteArrayOutputStream.close();
byte[] bytearray = byteArrayOutputStream.toByteArray();
BufferedImage imag=ImageIO.read(new ByteArrayInputStream(bytearray));
ImageIO.write(imag, "jpg", new File(dirName,"snap.jpg"));
这段代码读取图像文件,将其转换为byteArray,然后将其存储回去。 现在,对于我测试过的大多数图像文件,其大小都急剧减小到仅原始大小的15%。
有人可以解释为什么这样做会减小图像文件的大小。
在此过程中质量是否下降。
[我已经比较了http://driiqm.mpi-inf.mpg.de中的图像,它表明新图像的质量相同。]
答案 0 :(得分:1)
您将执行以下操作:
try (OutputStream out = new FileOutputStream(new File(dirName,"snap.jpg"))) {
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
JPEGEncodeParam eparm = encoder.getDefaultJPEGEncodeParam(img);
eparm.setQuality(quality, true);
encoder.setJPEGEncodeParam(eparm);
encoder.encode(img);
}
其中质量是介于0和1之间的浮点数。
答案 1 :(得分:1)
TLDR:您的结果与原始质量不同。 JPEG总是会降低一些质量,但是您的结果会降低很多质量。 Exif元数据已丢失,但这只是微不足道的差异。
我用您的书写方式测试了示例图像,然后测试了以最高质量进行书写(例如@MauricePerry编写的代码)。然后,我将它们与http://driiqm.mpi-inf.mpg.de和http://exif.regex.info/exif.cgi
进行了比较原始文件:
通过您的方法,我得到了:
我以最高的质量得到了
我不确定您如何假设图像具有相同的质量,因为您发布的网页存在很多差异。即使具有最高质量,它也会显示出差异,这是有道理的,因为JPEG是有损格式。 BufferedImage将图像数据表示为位图,并且在转换为JPEG时会丢失一些信息。这就是为什么我们拥有PNG等无损格式。
我也做了您所说的-将结果图像用作源图像,然后输入和输出相同。我将其与达到本地最小值进行比较。 JPEG->位图转换会生成位图,其中位图-> JPEG会生成相同的JPEG数据,因为您使用的是相同的功能(相同的质量,相同的采样)。但是,如果位图-> JPEG转换使用其他功能(例如,这次使用最高质量),则会导致质量损失更大。
答案 2 :(得分:0)
质量正在更改为默认值。您使用此默认值两次写入。
db_name = False, dbfilter = .
现在图像已转换为字节,并使用有损压缩进行压缩。
ImageIO.write(bufferedImage, "jpg", byteArrayOutputStream);
这也使用默认压缩。
ImageIO.write(imag, "jpg", new File(dirName,"snap.jpg"));
在此示例中,字节数组将包含最少的有损压缩,接近输入大小。要写出来,不要使用ImageIO再次读/写它。相反,我只是将字节直接写到文件中。