0

我的应用程序下载 Facebook 用户的 jpeg 个​​人资料图片,并对其进行 base64 编码。解码时,生成的 jpeg 质量和大小会显着降低。我该如何避免这种情况?

这是我下载/编码的方式:

// Download the profile picture.
BufferedImage image = ImageIO.read(new URL("http://facebook-profile-pic"));
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ImageIO.write(image, "jpeg", bos);

// Base64 encode it.
String imageData = new String(Base64.getEncoder().encode(bos.toByteArray()));

当我获取 imageData 的值并对其进行解码时,图像比原始下载 URL 中的图像小得多。

4

2 回答 2

0

与 Base64 之间的编码是完全无损的。保存时可能会发生质量损失。为防止这种情况,请ImageWriter直接使用(ImageIO.write已在内部使用,但无法控制设置):

ImageWriter writer = ImageIO.getImageWritersByFormatName("jpeg").next();
writer.setOutput(bos);

ImageWriteParam param = writer.getDefaultWriteParam();
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
param.setCompressionQuality(1.0F); // Highest quality

writer.write(image, new IIOImage(image, null, null), param);

此外,根据您使用的 API,您可能已经下载了低质量的图像。

于 2016-09-20T20:49:38.787 回答
0

解码时,生成的 jpeg 质量和大小显着降低

JPEG 是一种有损文件格式,ImageIO在写入 jpg 文件时使用默认的有损压缩度量。为了获得更高的质量(或无损),您需要通过JPEGImageWriteParam自己明确处理压缩质量。

//create the params    
JPEGImageWriteParam jpegParams = new JPEGImageWriteParam(null);
jpegParams.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
jpegParams.setCompressionQuality(1f);//set compression quality

请参阅此处的答案以写入文件。要写入内存,您需要使用MemoryCacheImageOutputStream

//write to output stream
ByteArrayOutputStream bos = new ByteArrayOutputStream();
MemoryCacheImageOutputStream ios = new MemoryCacheImageOutputStream(bos);
final ImageWriter writer = ImageIO.getImageWritersByFormatName("jpg").next();
writer.setOutput(ios);
writer.write(null, new IIOImage(image, null, null), jpegParams);
于 2016-09-20T20:50:35.397 回答