从原始数据的字节数组中获取缓冲图像

我正在使用JNA。 我从我的c ++方法获取原始数据的字节数组。 现在我被困在如何使用这个原始数据字节数组在java中获取缓冲图像。 我曾尝试过很少的东西来把它作为tiff图像,但我得到了成功。 这是我到目前为止尝试的代码。 这里我的字节数组包含16位灰度图像的数据。 我从x传感器设备获得这些数据。 现在我需要从这个字节数组中获取图像。

第一次尝试

byte[] byteArray = myVar1.getByteArray(0, 3318000);//array of raw data ImageInputStream stream1=ImageIO.createImageInputStream(newByteArrayInputStream(byteArray)); ByteArraySeekableStream stream=new ByteArraySeekableStream(byteArray,0,3318000); BufferedImage bi = ImageIO.read(stream); 

第二个尝试

  SeekableStream stream = new ByteArraySeekableStream(byteArray); String[] names = ImageCodec.getDecoderNames(stream); ImageDecoder dec = ImageCodec.createImageDecoder(names[0], stream, null); //at this line get the error ArrayIndexOutOfBoundsException: 0 RenderedImage im = dec.decodeAsRenderedImage(); 

我想我在这里失踪了。 由于我的数组包含原始数据,因此它不包含tiff图像的标题。 对吗? 如果是,则如何在字节数组中提供此标头。 最终如何从这个字节数组中获取图像?

为了测试我从我的本机方法得到正确的字节数组我将这个字节数组存储为.raw文件,在ImageJ软件中打开这个原始文件之后它播放了正确的图像,所以我的原始数据是正确的。 我唯一需要的是如何在图像字节数组中转换我的原始字节数组?

这是我用来将原始像素数据转换为BufferedImage 。 我的像素是16位符号:

 public static BufferedImage short2Buffered(short[] pixels, int width, int height) throws IllegalArgumentException { BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_USHORT_GRAY); short[] imgData = ((DataBufferShort)image.getRaster().getDataBuffer()).getData(); System.arraycopy(pixels, 0, imgData, 0, pixels.length); return image; } 

然后我使用JAI对生成的图像进行编码。 如果您还需要代码,请告诉我。

编辑:由于@Brent Nash对类似问题的回答 ,我的速度大大提高了。

编辑:为了完整起见,这里是无符号8位的代码:

 public static BufferedImage byte2Buffered(byte[] pixels, int width, int height) throws IllegalArgumentException { BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY); byte[] imgData = ((DataBufferByte)image.getRaster().getDataBuffer()).getData(); System.arraycopy(pixels, 0, imgData, 0, pixels.length); return image; } 

字节数组是否只包含像素数据或结构化图像文件(如TIFF等)实际上取决于您从何处获得它。 从提供的信息中回答这个问题是不可能的。

但是,如果它确实包含结构化图像文件,那么通常可以:

  • 在它周围包装一个ByteArrayInputStream
  • 将该流传递给ImageIO.read()

如果您只是字面上的原始像素数据,那么您有几个主要选项:

  • ‘手动’获取该像素数据,使其处于一个int数组中,ARGB格式中每个像素一个int(ByteBuffer和IntBuffer类可以帮助您处理字节)
  • 创建一个空白的BufferedImage,然后调用其setRGB()方法来设置先前准备的int数组中的实际像素内容

如果你知道你在使用位和字节做什么,我认为上面是最容易的。 但是,原则上,您应该能够执行以下操作:

  • 找到一个合适的WritableRaster.create …方法,该方法将创建一个包裹数据的WritableRaster对象
  • 将WritableRaster传递给相关的BufferedImage构造函数以创建图像。