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

Jon*_*ony 3 java bufferedimage bytearray jai

我正在使用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);
Run Code Online (Sandbox Code Playgroud)

第二个尝试

        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();
Run Code Online (Sandbox Code Playgroud)

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

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

Mat*_*ieu 7

这是我用来将原始像素数据转换为a的方法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;
}
Run Code Online (Sandbox Code Playgroud)

然后,我使用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;
}
Run Code Online (Sandbox Code Playgroud)

  • @ H.Aqjn只是将`DataBufferShort`改为`DataBufferByte`和`BufferedImage.TYPE_USHORT_GRAY`改为`BufferedImage.TYPE_BYTE_GRAY`(以及所有`short []`改为`byte []`)你就可以了. (2认同)

Nei*_*fey 4

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

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

  • 将 ByteArrayInputStream 包裹在其周围
  • 将该流传递给 ImageIO.read()

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

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

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

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