在Java中高效访问图像像素

时间:2016-09-27 14:35:43

标签: java image-processing

我需要编写一个重采样函数,它接收输入图像并用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;

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

2 个答案:

答案 0 :(得分:2)

最简单的方法(但不是最快)是使用栅格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

答案 1 :(得分:1)

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