下载和base64编码后显着的jpeg质量损失

时间:2016-09-20 20:25:05

标签: java compression base64 jpeg loss

我的应用程序下载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的图像小。

2 个答案:

答案 0 :(得分:0)

与Base64的编码完全无损。质量损失可能发生在保存时。为防止这种情况,请直接使用ImageWriterImageIO.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下载了低质量图像。

答案 1 :(得分: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

查看答案here以写入文件。要在内存中写入,您需要使用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);