BufferedImage getRGB vs Raster getSample

时间:2014-02-17 06:05:56

标签: java image-processing javax.imageio

我正在尝试用Java进行一些图像处理。我使用ImageIO库来读写图像。我可以通过以下两种方式读取图像像素值(可能还有其他方法不知道)。

  1. 使用BufferedImage的getRGB方法:  

    pixel = image.getRGB(x,y);

  2. 使用Raster的getSample方法:

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

  3. 上述两种方法有何不同?

1 个答案:

答案 0 :(得分:8)

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具有相同的“问题”,因此您可能需要“手动”转换/查找。


一如既往,取决于哪种方法更好。您必须查看每个用例,并确定哪些更重要。轻松/简单,或最佳性能(或最佳质量?)。