2016-09-20 66 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);