在 Java 中從圖像中獲取像素數組
一、概述
在本教程中,我們將學習如何從 Java 中的BufferedImage
實例獲取包含圖像信息(RGB 值)的像素數組。
2.什麼是BufferedImage類?
BufferedImage類是 Image 的子類,它描述了具有可訪問的圖像數據緩衝區的圖形圖像。 BufferedImage 由ColorModel和Raster組成。
ColorModel 描述瞭如何使用組件組合作為值元組來表示顏色。 Java 中的 ColorModel 類由可以返回特定像素的顏色值的方法組成。例如, getBlue(int pixel)
返回給定像素的藍色值。
此外,Raster 類包含像素數組中的圖像數據。 Raster 類由存儲圖像值的DataBuffer和描述像素如何存儲在 DataBuffer 中的SampleModel組成。
3. 使用getRGB()
第一種方法是使用 BufferedImage 類中的getRGB()
實例方法。
getRGB()
方法將指定像素的 RGB 值合併為一個整數並返回結果。此整數包含可使用實例的 ColorModel 訪問的 RGB 值。此外,為了獲得圖像中每個像素的結果,我們必須遍歷它們並分別為每個像素調用方法:
public int[][] get2DPixelArraySlow(BufferedImage sampleImage) {
int width = sampleImage.getWidth();
int height = sampleImage.getHeight();
int[][] result = new int[height][width];
for (int row = 0; row < height; row++) {
for (int col = 0; col < width; col++) {
result[row][col] = sampleImage.getRGB(col, row);
}
}
return result;
}
在上面的代碼片段中, result
數組是一個二維數組,其中包含圖像中每個像素的 RGB 值。這種方法比下一種方法更直接,但效率也較低。
4. 直接從DataBuffer
中獲取值
在這種方法中,我們首先從圖像中分別獲取所有的 RGB 值,然後手動將它們組合成一個整數。之後,我們像第一種方法一樣填充包含像素值的二維數組。這種方法比第一種方法更複雜但速度要快得多:
public int[][] get2DPixelArrayFast(BufferedImage image) {
byte[] pixelData = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
int width = image.getWidth();
int height = image.getHeight();
boolean hasAlphaChannel = image.getAlphaRaster() != null;
int[][] result = new int[height][width];
if (hasAlphaChannel) {
int numberOfValues = 4;
for (int valueIndex = 0, row = 0, col = 0; valueIndex + numberOfValues - 1 < pixelData.length; valueIndex += numberOfValues) {
int argb = 0;
argb += (((int) pixelData[valueIndex] & 0xff) << 24); // alpha value
argb += ((int) pixelData[valueIndex + 1] & 0xff); // blue value
argb += (((int) pixelData[valueIndex + 2] & 0xff) << 8); // green value
argb += (((int) pixelData[valueIndex + 3] & 0xff) << 16); // red value
result[row][col] = argb;
col++;
if (col == width) {
col = 0;
row++;
}
}
} else {
int numberOfValues = 3;
for (int valueIndex = 0, row = 0, col = 0; valueIndex + numberOfValues - 1 < pixelData.length; valueIndex += numberOfValues) {
int argb = 0;
argb += -16777216; // 255 alpha value (fully opaque)
argb += ((int) pixelData[valueIndex] & 0xff); // blue value
argb += (((int) pixelData[valueIndex + 1] & 0xff) << 8); // green value
argb += (((int) pixelData[valueIndex + 2] & 0xff) << 16); // red value
result[row][col] = argb;
col++;
if (col == width) {
col = 0;
row++;
}
}
}
return result;
}
在上面的代碼片段中,我們首先獲取圖像中每個像素的單獨 RGB 值,並將它們存儲在名為pixelData
的字節數組中。
例如,假設圖像沒有 alpha 通道(alpha 通道包含圖片的透明度信息), pixelData[0]
包含圖像中第一個像素的藍色值,而pixelData[1]
和pixelData[2]
包含分別是綠色和紅色值。同樣, pixelData[3]
到pixelData
[5]
包含第二個圖像像素的 RGB 值,依此類推。
得到值後,我們必須將它們組合成每個像素的一個整數。但在此之前,我們需要找出圖像是否有 alpha 通道。如果圖像有 alpha 通道,我們需要將四個值(紅色、綠色、藍色和透明度信息)組合成一個整數。如果沒有,我們只需要組合 RGB 值。
將所有值組合成一個整數後,我們將整數放入其在二維數組中的位置。
5.總結
在這篇簡短的文章中,我們學習瞭如何在 Java 中獲取包含圖像中每個像素的組合 RGB 值的二維數組。
與往常一樣,本文中使用的代碼片段可在 GitHub 上獲得。