如何从原始数据创建 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)
如果可以改进,我当然愿意接受建议,但总的来说它按预期工作。
I'm trying to get a BufferedImage from raw samples, but I get exceptions about trying to read past the available data range which I just don't understand. What I'm trying to do is:
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)
Unfortunately I get:
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)
The data is standard RGB with 1 byte padding (so that 1 pixel == 4 bytes) and the image size is 1366x24 px.
I finally got the code to run with the suggestion below. The final code is:
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)
If it can be improved, I'm open to suggestions of course, but in general it works as expected.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
setPixels
假定图像数据未打包。因此它正在寻找长度为 image.width*image.height*3 的输入,并从数组末尾运行。以下是解决问题的三个选项。
(1) 解压
imgbytes
使其长度增加 3 倍,并按照上面的方法进行操作。(2) 手动从
imgbytes
加载缓冲区,而不是使用setPixels
:(3) 不要使用
createDataBuffer
;如果您已经知道您的数据具有正确的格式,您可以自己创建适当的缓冲区(在本例中为DataBufferInt
):(您可能需要执行
imgbytes.clone
如果你的原始副本可能会被其他东西变异)。setPixels
assumes that the image data is not packed. So it's looking for an input of length image.width*image.height*3, and running off the end of the array.Here are three options for how to fix the problem.
(1) Unpack
imgbytes
so it is 3x longer, and do it the same way as above.(2) Manually load the buffer from
imgbytes
instead of usingsetPixels
:(3) Don't use
createDataBuffer
; if you already know that your data has the proper formatting you can create the appropriate buffer yourself (in this case, aDataBufferInt
):(you may need to do
imgbytes.clone
if your original copy could get mutated by something else).