1. 概述
在这个教程中,我们将学习如何从Java中的BufferedImage
实例获取包含图像信息(RGB值)的像素数组。
2. BufferedImage
类是什么?
BufferedImage
类是Image
类的子类,它描述了一个具有可访问图像数据缓冲区的图形图像。BufferedImage
由一个ColorModel
和一个Raster
组成。
ColorModel
描述了颜色如何使用一组组件的组合表示为值的元组。Java中的ColorModel
类包含方法,可以为特定像素返回颜色值,例如getBlue(int pixel)
返回给定像素的蓝色值。
此外,Raster
类以像素数组的形式存储图像数据。Raster
类由一个DataBuffer
组成,用于存储图像值,以及一个SampleModel
,用于描述像素如何存储在DataBuffer
中。
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上找到。