2016-09-20 34 views
0

我的应用下载Facebook用户的jpeg个人资料图片和base64编码。对其进行解码时,生成的JPEG质量和尺寸会显着减小。我如何避免这种情况?下载后显着jpeg质量损失和base64编码

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

// 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的方式更小。

+1

'新的字符串(字节阵列)'是不可靠的,因为它使用的底层系统的默认字符集编码的字节数。如果该字符集是UTF-8或某些ISO-8859字符集,它将适用于Base64编码的字节,但如果是其他内容,则您的数据将被损坏。使用'String imageData = Base64.getEncoder()。encodeToString(bos.toByteArray());'而不是。 – VGR

+0

JPEG是无损文件格式,写入时ImageIO使用特定质量。为了获得更高质量和/或无损,您需要明确指定质量 – copeg

回答

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你使用。

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);