java 从原始数据的字节数组中获取缓冲图像
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10720212/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Get buffered image from byte array of raw data
提问by Jony
I am using JNA. and i am getting byte array of raw data from my c++ method. Now i am stuck how to get buffered image in java using this raw data byte array. I had tried few things to get it as tiff image but i dint get success. this are the code i tried so far. here my byte array contains data for 16 bit gray scale image. i get this data from x-sensor device. and now i need to get image from this byte array.
我正在使用 JNA。我从我的 C++ 方法中获取原始数据的字节数组。现在我被困在如何使用这个原始数据字节数组在 java 中获取缓冲图像。我尝试了一些方法来将其作为 tiff 图像,但我没有成功。这是我到目前为止尝试过的代码。这里我的字节数组包含 16 位灰度图像的数据。我从 x 传感器设备中获取这些数据。现在我需要从这个字节数组中获取图像。
FIRST TRY
第一次尝试
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);
SECOND TRY
第二次尝试
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();
I think i am missing here. As my array is containing raw data ,it does not containthen header for tiff image. m i right? if yes then how to provide this header in byte array. and eventually how to get image from this byte array?
我想我在这里失踪了。由于我的数组包含原始数据,因此它不包含 tiff 图像的标题。对吗?如果是,那么如何在字节数组中提供此标头。最终如何从这个字节数组中获取图像?
to test that i am getting proper byte array from my native method i stored this byte array as .raw file and after opening this raw file in ImageJ software it sows me correct image so my raw data is correct. The only thing i need is that how to convert my raw byte array in image byte array?
为了测试我是否从我的本机方法中获得了正确的字节数组,我将此字节数组存储为 .raw 文件,在 ImageJ 软件中打开此原始文件后,它向我播送正确的图像,因此我的原始数据是正确的。我唯一需要的是如何在图像字节数组中转换我的原始字节数组?
回答by Matthieu
Here is what I am using to convert raw pixel data to a BufferedImage
. My pixels are signed 16-bit:
这是我用来将原始像素数据转换为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;
}
I'm then using JAI to encode the resulting image. Tell me if you need the code as well.
然后我使用 JAI 对生成的图像进行编码。告诉我你是否也需要代码。
EDIT: I have greatly improved the speed thanks to @Brent Nash answeron a similar question.
编辑:由于@Brent Nash对类似问题的回答,我大大提高了速度。
EDIT: For the sake of completeness, here is the code for unsigned 8 bits:
编辑:为了完整起见,这里是无符号 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;
}
回答by Neil Coffey
Whether or not the byte array contains literally just pixel data or a structured image file such as TIFF etc really depends on where you got it from. It's impossible to answer that from the information provided.
字节数组是否仅包含像素数据或结构化图像文件(如 TIFF 等)实际上取决于您从何处获取它。从提供的信息中无法回答这个问题。
However, if it does contain a structured image file, then you can generally:
但是,如果它确实包含结构化图像文件,那么您通常可以:
- wrap a ByteArrayInputStream around it
- pass that stream to ImageIO.read()
- 在它周围包裹一个 ByteArrayInputStream
- 将该流传递给 ImageIO.read()
If you just have literally raw pixel data, then you have a couple of main options:
如果您只有字面上的原始像素数据,那么您有几个主要选择:
- 'manually' get that pixel data so that it is in an int array with one int per pixel in ARGB format (the ByteBuffer and IntBuffer classes can help you with twiddling about with bytes)
- create a blank BufferedImage, then call its setRGB() method to set the actual pixel contents from your previously prepared int array
- “手动”获取该像素数据,使其位于一个 int 数组中,每个像素一个 int 为 ARGB 格式(ByteBuffer 和 IntBuffer 类可以帮助您处理字节)
- 创建一个空白的 BufferedImage,然后调用它的 setRGB() 方法来设置之前准备好的 int 数组中的实际像素内容
I think the above is easiest if you know what you're doing with the bits and bytes. However, in principle, you should be able to do the following:
我认为如果你知道你在用比特和字节做什么,上面的方法是最简单的。但是,原则上,您应该能够执行以下操作:
- find a suitable WritableRaster.create... method method that will create a WritableRaster object wrapped around your data
- pass that WritableRaster into the relevant BufferedImage constructor to create your image.
- 找到一个合适的 WritableRaster.create... 方法方法,该方法将创建一个 WritableRaster 对象围绕您的数据
- 将该 WritableRaster 传递给相关的 BufferedImage 构造函数以创建您的图像。