2016-01-22 16 views
0

我已閱讀大多數問題here,here,bug和其他。使用從ImageIO庫自身創建的jpg文件進行JPEG顏色值更改

一個區別是所有的帖子都在談論外部圖像被讀取。 但是我是從ImageIO庫本身創建jpg圖像我正在將該圖像寫入文件並讀取相同的圖像文件,但是在像素值方面存在差異。

這裏是我的代碼:

 BufferedImage j = new BufferedImage(100,100,BufferedImage.TYPE_INT_RGB); 
     Graphics2D jg = j.createGraphics(); 
     jg.setColor(Color.GREEN); 
     jg.fillRect(0, 0, 100, 100); 
     jg.dispose(); 
     File gr = new File("d:/pics/green.jpeg"); 
     ImageIO.write(j,"jpeg",gr); 
     BufferedImage grbr = ImageIO.read(gr); 
     System.out.format("expected:%s\tactual::%s\n", j.getRGB(40,40), grbr.getRGB(40,40)); 
     System.out.format("expectedG:%s\tactualG::%s", Color.GREEN.getRGB(), grbr.getRGB(40,40)); 

輸出:

expected:-16711936 actual::-16711935 
expectedG:-16711936 actualG::-16711935 

我從我看到的幫助,下面

問題閱讀本摘錄其他所有圖像裝載機假設在這種情況下,數據爲YCbCr, 除ImageIO外,其中ImageIO在通道1和通道2中爲RGB時爲 不被二次採樣。因此,檢查前4個字節是否爲FF FF D8 E1 ,如果是這樣,通道1和2是否有子採樣

我讀了green.jpeg的前幾個字節被寫入後像this文件如下

FF FF D8 E0 00 10 4A 46 49 46 00

我維基百科上讀到JFIF,發現上面的序列是一個不按照什麼被提及作爲here。但是這裏不適用,因爲我創建了一個簡單的RGB類型圖像而不是YCbCr類型。

那麼爲什麼在ImageIO中創建和讀取簡單圖像會產生不同的結果呢?提前致謝。

+3

無論您如何創建或讀取圖像,JPEG都是*有損*格式。如果您想要返回完全相同的值,則需要使用不同的格式,例如PNG或TIFF。 – haraldK

+2

您鏈接的問題/錯誤是關於YCbCr編碼的EXIF JPEG(由FF D8 FF E1標識)被解碼爲RGB,並導致所有錯誤的顏色。 ImageIO默認寫入JFIF JPEG(由FF D8 FF E0'標識),並且它們被正確解碼。無論如何,你似乎只能在解碼後的RGB值上經歷微小的差異。這是使用JPEG壓縮時預期的。 – haraldK

+0

謝謝haraldK! – chebus

回答

0

RGB和YCbCr顏色空間的色域是不同的。這是你第一次有變化。 JPEG過程中有各種步驟可能會引入舍入錯誤。 JPEG中的量化過程更改值。

你的比較顯示非常微小的變化,與JPEG正常。