2011-09-19 29 views
4

我想讀取,重新縮放和保存圖像在一個Servlet。這是相關代碼:閱讀JPEG:ImageIO.read()弄亂顏色空間

BufferedImage image = ImageIO.read(file); 

BufferedImage after = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); 
AffineTransform at = AffineTransform.getScaleInstance(factor, factor); 
AffineTransformOp scaleOp = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR); 
after = scaleOp.filter(image, null); 

ImageIO.write(after, "JPG", file)); 

原始文件是一個普通的RGB-JPEG,但是當我打開和保存文件弄出來的CMYK-JPEG。即使我不重新調整圖像,只是打開和關閉圖像導致問題發生這種情況。

當我打開PNG或GIF時,一切都很好。有人知道該怎麼做嗎?我希望ImageIO的read-Method保留原來的色彩空間。

如果還有另一種方式閱讀jpeg的舒適方式?

感謝您的任何建議!

+2

創建'after'和然後用'scaleOp.filter'覆蓋它。它是否正確?所以即使你認爲它是'RGB'圖像可能不是RGB?如果你希望'後'是RGB,那麼在你進行變換之前,你可能需要'將'圖像'繪製'到*之後。 –

+1

這是一個很好的提示:過濾器方法返回一個全新的BufferedImage。所以現在我知道,圖像在讀取時不會被「着色」,而是在我的轉換之後。我嘗試使用'graphics.drawImage(image,scaleOp,0,0)'將原始圖像繪製到目標圖像上,現在它可以正確轉換。謝謝你的幫助! –

+1

很高興它的工作!我將添加一個答案,以便qn可以關閉。 –

回答

4

您創建after,然後用scaleOp.filter覆蓋它。它是否正確?所以你的after圖像可能不是RGB,即使你認爲它是?如果你想after是RGB,那麼你可能需要''到'after'繪製變形之前。

1

我有同樣的問題,並發現此頁。

我嘗試了上面的建議,用正確的類型創建一個BufferedImage,並將它用作過濾器調用中的after圖像而不是null;這確實解決了這個問題。

1

ImageIO.read忽略所有嵌入式元數據,包括嵌入式顏色配置文件,該配置文件定義了RBG值如何映射到物理設備(如屏幕或打印機)。

您可以單獨讀取元數據並將其傳遞給ImageIO.write,但將圖像轉換爲(默認)sRGB色彩空間並忽略元數據會更容易。

如果你不介意丟失的元數據,更換

after = scaleOp.filter(image, null); 

after = scaleOp.filter(image, after); 

AffineTransformOp.filter文檔:

If the color models for the two images do not match, a color conversion into the destination color model is performed.