我编写的图像处理代码将像素数据复制成整数数组,如下所示:
void processImage(BufferedImage source) {
WritableRaster raster = source.getRaster();
int numBands = raster.getNumBands();
int height = raster.getHeight();
int width = raster.getWidth();
int[] pixelRow = new int[width * numBands];
for (int i = 0; i < height; i++) {
raster.getPixels(raster.getMinX(), raster.getMinY() + i, width, 1, pixelRow);
// do some processing
}
// create a new image
return newImage;
}
该代码适用于我目前测试的图像。对于具有3个波段(没有alpha通道)的图像,pixelRow
数组似乎始终按照红色,绿色和蓝色的顺序接收像素分量,对于具有4个波段的那些(以及带有红色,绿色,蓝色和Alpha的顺序) alpha通道)。
但是,我找不到任何说明这一点的说明。是否保证我将始终按顺序获取像素组件?有没有描述这个的规范?
答案 0 :(得分:7)
SampleModel.getPixel()
(由Raster.getPixel()
内部使用)以band的顺序返回像素分量。虽然可以通过编程方式创建一个伪造的SampleModel
实例,其带宽顺序与RGB不同,但SampleModel
的实例通常是由构造{{1}的ColorModel
创建的SampleModel
带的顺序与ColorModel
中的颜色分量顺序相同。
颜色模型组件的顺序记录在java.awt.image.ColorModel javadoc:
中
ColorModel
的颜色分量的数量,顺序和解释由ColorSpace
指定。
理论上你应该检查颜色空间是否来自RGB系列:
public static void processImage( BufferedImage source )
{
ColorSpace colorSpace = source.getColorModel().getColorSpace();
if ( dumpColorSpaceProperties ) {
System.out.printf( "color space type: %d, is RGB = %s%n", colorSpace.getType(), colorSpace.isCS_sRGB() );
for ( int i = 0; i < colorSpace.getNumComponents(); i++ ) {
System.out.printf( "component %d = %s%n", i, colorSpace.getName( i ) );
}
}
if ( colorSpace.getType() == ColorSpace.TYPE_RGB ) {
// guaranteed RGB(A) order, proceed with raster.getPixels()
} else {
// well, find a way to convert from that space into RGB
throw new AssertionError( "color space type = " + colorSpace.getType() );
}
}
在实践中,这一切都取决于图像的来源。通过BufferedImage(width, height, imageType)
创建的图像始终使用RGB空间。如果图像文件格式支持不同的颜色空间,并且该特定图像文件使用非RGB空间,则从文件获取的图像可以使用其他颜色空间。
如果你知道图像源,你不需要检查色彩空间,你可以假设Raster.getPixels()
的RGB(A)输出。
ColorSpace.getName(int)
来源可以深入了解在实践中可能遇到的大多数颜色集的默认组件。
答案 1 :(得分:1)
答案 2 :(得分:0)
本文档PNG Specification似乎表明您所描述的顺序实际上是标准的。第3.1.44节同样含义。但是,在涉及颜色的其他情况下,似乎通常是[alpha,]红色,绿色,蓝色,如Microsoft here.所述。看到java.awt.image包的类中的几个方法使用或返回类似的数组样本,假设这个订单是标准的应该是非常安全的。尽管如此,我找不到指定此行为的实例。
答案 3 :(得分:0)
我也没有明确的答案。但是更有可能在ColorModel实例中找到相关信息(而不是在Raster或SampleModel实例中)。
可以直接从 BufferedImage 访问 ColorModel 实例。