BufferedImage getRGB vs Raster getSample [英] BufferedImage getRGB vs Raster getSample

查看:171
本文介绍了BufferedImage getRGB vs Raster getSample的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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


  1. 使用BufferedImage的getRGB方法:



    pixel = image.getRGB(x,y);


  2. 使用Raster的getSample方法:



    WritableRaster raster = image.getRaster();

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


上述两种方法有什么区别?

解决方案

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; //在第一次调用getDataElements时初始化像素

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

这将为您提供原生值数据缓冲区,没有任何转换。



然后,您需要对每种传输类型进行特殊处理(请参阅 DataBuffer 你想要支持,也许是非标准类型的常见后备。



这与像素值与标准化的方法2相同问题 RGB值,因此您可能需要手动转换/查找。






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


I am trying to do some image processing in Java. I used ImageIO library for reading and writing images. I can read the image pixel value in two ways as follows (there might be other methods).

  1. Using BufferedImage's getRGB method:

    pixel = image.getRGB(x,y);

  2. Using Raster's getSample method:

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

What is the difference in above two approach?

解决方案

1: The first approach will always return a pixel in int ARGB format, and in the sRGB color space. Regardless of the image's internal representation. This means that unless the image's internal representation is TYPE_INT_ARGB, some conversion has to be done. This is sometimes useful, because it's predictable, but just as often it's quite slow. As an example, color space conversion is quite expensive. Also, if the image has higher precision than 8 bits per sample and/or 4 samples per pixel, precision loss occurs. This may or may not be acceptable, given your use case.

2: The second approach may give you a pixel value, but not in all cases, as it gives you the sample value at (x,y) for the the band 0 (the first band). For TYPE_INT_ARGB this will be the same as the pixel value. For TYPE_BYTE_INDEXED this will be the index to use in the look up table (you need to look it up to get the pixel value). For TYPE_3BYTE_BGR this will give you the blue value only (you need to combine it with the samples in band 1 and 2 to get the full pixel value). Etc. for other types. For samples that are not internally represented as an int, data type conversion occurs (and in rare cases precision loss). It might work for you, but I've never had much use for the getSample(...) methods.

Instead I suggest you look into what I believe to be the fastest way to get at pixel data. That is using the getDataElements method:

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

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

This will give you the "native" values from the data buffer, without any conversion.

You then need to have special handling for each transfer type (see the DataBuffer class) you want to support, and perhaps a common fallback for non-standard types.

This will have the same "problem" as your approach 2 for pixel values vs normalized RGB values, so you might need to convert/look up "manually".


What approach is better, as always, depends. You have to look at each use case, and decide what's more important. Ease/simplicity, or the best possible performance (or perhaps best quality?).

这篇关于BufferedImage getRGB vs Raster getSample的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆