【问题标题】:Efficient access to image pixels in Java在 Java 中高效访问图像像素
【发布时间】:2016-09-27 14:35:42
【问题描述】:

我需要编写一个重采样函数来获取输入图像并在 Java 中生成输出图像。

图像类型为 TYPE_BYTE_GRAY。

由于所有像素都将被读取和写入,我需要一种有效的方法来访问图像缓冲区。

我不相信像 getRGB/setRGB 这样的方法会合适,因为它们会执行转换。我追求的功能可以让我最直接地访问存储的缓冲区,具有高效的地址计算、没有图像复制和最小的开销。

你能帮帮我吗?我找到了许多类型的示例,例如使用 WritableRaster,但没有一个足够完整。


更新

正如@FiReTiTi 所建议的,诀窍是从图像中获取WritableRaster,并将其关联的缓冲区作为DataBufferByte 对象获取。

DataBufferByte SrcBuffer= (DataBufferByte)Src.getRaster().getDataBuffer();

然后您可以选择使用其getElem/setElem 方法直接访问缓冲区

SrcBuffer.setElem(i, getElem(i) + 1);

或提取字节数组

byte [] SrcBytes= SrcBuffer.getData();
SrcBytes[i]= SrcBytes[i] + 1;

这两种方法都有效。我还不知道性能有什么不同...

【问题讨论】:

  • 您想对从图像中检索到的像素做什么?
  • @px06 如前所述,我正在编写一个(自定义)重采样函数,但这对答案有何影响?
  • 第二个开始直接访问数组,我会说它必须更快。但我不确定它有多快。很高兴它成功了。
  • 对不起,显然是“存在”,而不是“开始”。

标签: java image-processing


【解决方案1】:

最简单(但不是最快)的方法是使用光栅myimage.getRaster(),然后使用方法getSample(x,y,c)setSample(x,y,c,v) 访问和修改像素值。

最快的方法是访问 DataBuffer(直接访问表示图像的数组),因此对于 TYPE_BYTE_GRAY BufferedImage,它将是byte[] buffer = ((DataBufferByte)myimage.getRaster().getDataBuffer()).getData()。请注意像素是在byte 而不是unsigned byte 上编码的,所以每次要读取像素值时,都必须使用buffer[x] & 0xFF

这是一个简单的测试:

BufferedImage image = new BufferedImage(256, 256, BufferedImage.TYPE_BYTE_GRAY) ;
byte[] buffer = ((DataBufferByte)image.getRaster().getDataBuffer()).getData() ;
System.out.println("buffer[0] = " + (buffer[0] & 0xFF)) ;
buffer[0] = 1 ;
System.out.println("buffer[0] = " + (buffer[0] & 0xFF)) ;

这是输出:

buffer[0] = 0
buffer[0] = 1

【讨论】:

  • (不是我的反对票。)这不起作用,图像保持不变。
  • 你能分享你的代码吗?我每天都在我的图书馆中使用它,而且效果很好:-)
  • 不用担心投反对票,我已经习惯了仇恨。当然是同一个人否决了您的问题
  • 我现在明白了:由于缩小(我的测试图像很大),我的更改是不可见的!愚蠢的我 !我会更新我的帖子。
  • 附注:通过image.getRaster().getDataBuffer()buffer.getData() 直接访问数据是直接访问数据 的最快方式(假设您完全确定图像类型以及如何解释返回的数组!)。但它会使图像“无法跟踪”,这大致意味着它将不再保存在 VRAM 中,并且 绘制此图像,例如在带有graphics.drawImage(...) 的组件中会变得慢得多. (这可能与您的特定情况无关,但应该指出恕我直言)。
【解决方案2】:

可以获得底层缓冲区yourimage.getData().getDataBuffer(),但由于这是一个长数组,因此需要进行一些转换。您可以通过将某些元素设置为极值来找到像素顺序并渲染图片以查看像素是如何受到影响的。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-05-21
  • 2023-03-28
  • 2012-11-10
  • 2018-02-09
  • 1970-01-01
  • 1970-01-01
  • 2013-07-28
相关资源
最近更新 更多