2010-11-20 70 views
9

我试图从原始样本中获取BufferedImage,但是我试图读取超出可用数据范围的例外情况,这些数据范围我只是不明白。我正在试图做的是:如何从原始数据创建BufferedImage

val datasize = image.width * image.height 
val imgbytes = image.data.getIntArray(0, datasize) 
val datamodel = new SinglePixelPackedSampleModel(DataBuffer.TYPE_INT, image.width, image.height, Array(image.red_mask.intValue, image.green_mask.intValue, image.blue_mask.intValue)) 
val buffer = datamodel.createDataBuffer 
val raster = Raster.createRaster(datamodel, buffer, new Point(0,0)) 
datamodel.setPixels(0, 0, image.width, image.height, imgbytes, buffer) 
val newimage = new BufferedImage(image.width, image.height, BufferedImage.TYPE_INT_RGB) 
newimage.setData(raster) 

不幸的是我得到:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 32784 
    at java.awt.image.SinglePixelPackedSampleModel.setPixels(SinglePixelPackedSampleModel.java:689) 
    at screenplayer.Main$.ximage_to_swt(Main.scala:40) 
    at screenplayer.Main$.main(Main.scala:31) 
    at screenplayer.Main.main(Main.scala) 

的数据为标准的RGB 1个字节的填充(使1个像素== 4个字节)和图像尺寸是1366x24像素。


我终于得到了代码运行下面的建议。最后的代码是:

val datasize = image.width * image.height 
val imgbytes = image.data.getIntArray(0, datasize) 

val raster = Raster.createPackedRaster(DataBuffer.TYPE_INT, image.width, image.height, 3, 8, null) 
raster.setDataElements(0, 0, image.width, image.height, imgbytes) 

val newimage = new BufferedImage(image.width, image.height, BufferedImage.TYPE_INT_RGB) 
newimage.setData(raster) 

如果能够改善,我接受,当然建议,但总的来说它按预期工作。

回答

10

setPixels假设图像数据是而不是打包。所以它正在寻找一个长度为image.width * image.height * 3的输入,并在数组的末尾运行。

以下是三种解决问题的方法。

(1)解压缩imgbytes,使其延长3倍,并按上述方法进行。

(2)手动从imgbytes加载,而不是使用setPixels缓冲器:

var i=0 
while (i < imgbytes.length) { 
    buffer.setElem(i, imgbytes(i)) 
    i += 1 
} 

(3)不使用createDataBuffer;如果你已经知道你的数据具有正确的格式,你可以自己创建适当的缓冲(在这种情况下,DataBufferInt):

val buffer = new DataBufferInt(imgbytes, imgbytes.length) 

(你可能需要做imgbytes.clone,如果你的原件可能会被什么东西得到突变其他)。

+0

我试过这些解决方案,但要么我得到不相关的垃圾或黑屏。如果我查看它的十六进制转储,数据是正确的。你能提供一个实际从imgbytes到BufferedImage的短片段吗?这将非常感谢:) – viraptor 2010-11-26 19:21:04

+0

如果你可以提供代码,在你的例子中创建'图像',当然。或者,如果您不关心数据如何进入,我会创建一个不是来自图像的示例。 – 2010-11-26 20:22:35

+0

这是我从Xorg直接获得的自定义对象。如果你可以用已知的'height','width'和每个像素的4个字节组件(RGB order + 1byte padding)或单个int(相同格式)的数组来完成,我可以计算出其余部分。我失败的部分可能是缓冲区<->栅格交互(我甚至不确定是否需要这两者)。非常感谢。 – viraptor 2010-11-26 20:31:30