代码之家  ›  专栏  ›  技术社区  ›  viraptor

如何从原始数据创建BufferedImage

  •  9
  • viraptor  · 技术社区  · 14 年前

    我试图从原始样本中获取一个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)
    

    如果可以改进的话,我当然愿意接受建议,但总的来说,它是按预期工作的。

    1 回复  |  直到 14 年前
        1
  •  10
  •   Rex Kerr    14 年前

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

    这里有三种解决问题的方法。

    (1)开箱 imgbytes 所以它是3倍长,做的方式和上面一样。

    (2)手动加载缓冲区 字节 而不是使用 设置像素 :

    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 如果你的原稿能被别的东西变异)。