在BufferedImage的int[]像素数组中工作

6
当使用setRGBgetRGB 方法处理 BufferedImage 时,我注意到两件事情:
  1. 在某些系统上,setRGBgetRGB 方法的速度非常慢(比修改 int[] 数组慢两个数量级)。

  2. 不能保证setRGB 后紧跟的 getRGB 返回的是相同的像素。

由于 JavaDoc 中的setRGB 已经明确说明了这一点:

...对于具有 IndexColorModel 的图像, 将选择最接近颜色的索引。

因此我可以直接操作 BufferedImage 的 int[] 像素,例如:

 int[] a = ((DataBufferInt) tmp.getRaster().getDataBuffer()).getData();

我想知道:在直接操作 int[] 像素时,是否存在任何已知的缺点或需要注意的问题?

2个回答

4

getData()提供对底层int数组的访问,正是为了进行优化,因此其优点很可能超过缺点。

缺点取决于您如何使用缓冲图像。如果您在编辑时将其绘制到屏幕上,可能会在屏幕上遇到一些伪影(如像素不能及时着色),这时您应该考虑双缓冲(每次刷新需要复制整个图像)。


+1 但您能否提供更多关于如何实现双缓冲的信息? - SyntaxT3rr0r
如何执行双缓冲取决于多个因素,例如您要显示的内容、其大小、图形引擎、所需的刷新率快慢、是否能够利用图形卡提供的功能等。但基本的实现方式是拥有一个您可以修改的缓冲区和一个您可以展示的缓冲区,在完成修改后将修改后的缓冲区复制到展示缓冲区上。一个好的方法是先将修改缓冲区中的数据复制到临时缓冲区中,以便将显示缓冲区分配给临时缓冲区是一个快速操作。 - Ben Taitelbaum
这里存在一个读者/写者问题,您必须确保不尝试显示正在被复制的缓冲区。如果您在单个线程中执行所有操作,则可以使用类似于 if (doneCopying) { displayBuf = tmpBuf; } draw(displayBuf); 的方法来解决问题。 - Ben Taitelbaum
非常感谢提供的信息,我可能会在未来几天内创建一个详细的问题,询问如何在我的特定情况下进行双缓冲。 - SyntaxT3rr0r

0

不确定这是否与您的问题相关,但是当使用方法{{link1:getSubimage(int x,int y,int w,int h)}}创建BufferedImage时,您将遇到问题。

返回由指定矩形区域定义的子图像。返回的BufferedImage与原始图像共享相同的数据数组。

尽管被描述为getTileGridXOffset()getTileGridYOffset()方法返回偏移量,但它们返回的偏移量始终为零:

返回瓷砖网格相对于原点的x偏移量,例如,瓷砖(0,0)的位置的x坐标。 这总是零。

但是,因为您无法(据我所知)访问光栅的scanlineStride字段,因此您将无法获取数组的正确索引。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接