2014-02-17 50 views
4

我想在Java中做一些圖像處理。我使用ImageIO庫來讀取和寫入圖像。我可以按照以下兩種方式讀取圖像像素值(可能有其他方法)。BufferedImage getRGB vs柵格getSample

  1. 使用的BufferedImage的方法的getRGB:

    像素= image.getRGB(X,Y);

  2. 使用光柵的方法的getSample:

    的WritableRaster光柵= image.getRaster();
    pixel = raster.getSample(x,y,0);

以上兩種方法有什麼區別?

回答

7

1:第一種方法將始終以int ARGB格式和sRGB顏色空間返回一個像素。無論圖像的內部表現如何。這意味着除非圖像的內部表示是TYPE_INT_ARGB,否則必須進行一些轉換。這有時是有用的,因爲它是可預測的,但同樣經常很慢。例如,色彩空間轉換非常昂貴。另外,如果圖像具有比每個樣本8位和/或每個像素4個樣本更高的精度,則會發生精度損失。根據您的使用情況,這可能會也可能不會被接受。

2:第二種方法可能會給你一個像素值,但不是在所有情況下,因爲它給出了0(第一個帶)在(x,y)處的樣本值。對於TYPE_INT_ARGB,這將與像素值相同。對於TYPE_BYTE_INDEXED,這將是查找表中使用的索引(您需要查看它以獲取像素值)。對於TYPE_3BYTE_BGR,這隻會給你藍色值(你需要將它與帶1和2中的樣本結合以獲得全像素值)。等等其他類型。對於非內部表示爲int的樣本,會發生數據類型轉換(並且在極少數情況下會發生精度損失)。它可能適用於您,但我從來沒有用過getSample(...)方法。

相反,我建議你看看我認爲是獲取像素數據的最快方法。這是使用getDataElements方法:

Object pixel = null; // pixel initialized on first invocation of getDataElements 

for (y) { 
    for (x) { 
     pixel = raster.getDataElements(x, y, pixel); 
    } 
} 

這會給你從數據緩衝區中的「原生」的價值觀,無需任何轉換。

然後,您需要針對每種傳輸類型(請參見DataBuffer類)進行特殊處理,這可能是非標準類型的普遍回退。

對於像素值與標準化的RGB值,這將與您的方法2具有相同的「問題」,因此您可能需要「手動」轉換/查找。


與往常一樣,哪種方法更好取決於。你必須看看每個用例,並確定哪些更重要。輕鬆/簡單,還是最好的表現(或者最好的質量?)。

+0

非常明確和詳細的解釋。非常感謝。你清除了我。我有一個簡單的查詢。通常的情況是什麼?如果我從互聯網下載圖像並嘗試使用第二種方法,那麼它是否會返回正常像素。你能否介紹一些在正常情況下可能遇到其他圖像類型的實際場景? –

+0

@BibekSubedi:你下載了什麼樣的圖片? :-)不同的格式以不同的方式存儲像素(並且ImageIO讀卡器插件可能使用不同的表示)。 「Normal case」可能來自BufferedImage.TYPE_ *常量。考慮GIF/PNG與調色板與真彩色PNG與PNG與alpha,或RGB JPEG與灰色JPEG。 – haraldK

+0

好的,我明白了。現在我得到了我的答案。再次感謝你。 –