如何从原始数据创建 BufferedImage

发布于 2024-10-03 12:41:26 字数 1564 浏览 8 评论 0原文

我试图从原始样本中获取 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

沦落红尘 2024-10-10 12:41:27

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如果你的原始副本可能会被其他东西变异)。

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 using setPixels:

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

(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, a DataBufferInt):

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

(you may need to do imgbytes.clone if your original copy could get mutated by something else).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文