如何在Java中将byte []转换为BufferedImage?

Jef*_*let 23 arrays byte bufferedimage

我发布这个帖子是因为我在处理Java中的图片时遇到了一些困难.我希望能够将图片转换为byte []数组,然后才能进行反向操作,这样我就可以更改每个像素的RGB,然后创建一个新图片.我想使用这个解决方案,因为BufferedImage的setRGB()和getRGB()对于巨大的图片来说可能太慢了(如果我错了,请纠正我).

我在这里阅读了一些帖子来获取byte []数组(例如这里),以便每个像素由包含红色,绿色和蓝色值的数组的3或4个单元格表示(带有额外的alpha值,当有是4个细胞),这对我来说非常有用且易于使用.这是我用来获取这个数组的代码(存储在我创建的PixelArray类中):

public PixelArray(BufferedImage image)
{
    width = image.getWidth();
    height = image.getHeight();
    DataBuffer toArray = image.getRaster().getDataBuffer();
    array = ((DataBufferByte) toArray).getData();
    hasAlphaChannel = image.getAlphaRaster() != null;
}
Run Code Online (Sandbox Code Playgroud)

我的大麻烦是我没有找到任何有效的方法将此byte []数组转换为新图像,如果我想转换图片(例如,删除蓝色/绿色值并仅保留红色值).我试过这些解决方案:

1)创建一个DataBuffer对象,然后创建一个SampleModel,最后创建一个WritableRaster,然后创建BufferedImage(带有额外的ColorModel和Hashtable对象).它没有用,因为我显然没有我需要的所有信息(我不知道什么是BufferedImage()构造函数的Hashtable).

2)使用ByteArrayInputStream.这不起作用,因为ByteArrayInputStream所期望的byte []数组与我的无关:它代表文件的每个字节,而不是每个像素的每个分量(每个像素有3-4个字节)......

有人能帮助我吗?

hee*_*ong 34

试试这个:

private BufferedImage createImageFromBytes(byte[] imageData) {
    ByteArrayInputStream bais = new ByteArrayInputStream(imageData);
    try {
        return ImageIO.read(bais);
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 一些主持人可以将此删除作为已接受的答案,因为它是错误的. (18认同)
  • 在快速测试中,您的方法返回"null",因为我的`ImageIO`没有理解原始流的`ImageInputStreamSPI`. (16认同)

小智 10

我尝试过这里提到的方法,但由于某些原因,它们都没有奏效.使用ByteArrayInputStreamImageIO.read(...)返回null,而byte[] array = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();返回图像数据的副本,而不是直接引用它们(另请参见此处).

但是,以下工作对我有用.让我们假设图像数据的尺寸和类型是已知的.我们也是byte[] srcbuf要转换成数据的缓冲区BufferedImage.然后,

  1. 例如,创建一个空白图像

    img=new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
    
    Run Code Online (Sandbox Code Playgroud)
  2. 将数据数组转换为Raster并用于setData填充图像,即

    img.setData(Raster.createRaster(img.getSampleModel(), new DataBufferByte(srcbuf, srcbuf.length), new Point() ) );
    
    Run Code Online (Sandbox Code Playgroud)


Mar*_*mus 6

BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
byte[] array = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
System.arraycopy(pixelArray, 0, array, 0, array.length);
Run Code Online (Sandbox Code Playgroud)

当您尝试使用生成的图像的Graphics对象时,此方法确实会失去同步.如果您需要在图像上绘制,请构建第二个图像(可以是持久的,不是每次都构造但重新使用),drawImage第一个图像就是它.


Jef*_*ght 6

有几个人赞成接受的答案是错误的评论。

如果接受的答案不起作用,可能是因为 Image.IO 不支持您正在尝试的图像类型,例如 tiff 图像。

要使其工作,您需要添加一个额外的 jar 来处理图像类型。

您可以添加jai-imageio-core-1.3.1.jar到您的类路径:

    <!-- https://mvnrepository.com/artifact/com.github.jai-imageio/jai-imageio-core -->
    <dependency>
        <groupId>com.github.jai-imageio</groupId>
        <artifactId>jai-imageio-core</artifactId>
        <version>1.3.1</version>
    </dependency>
Run Code Online (Sandbox Code Playgroud)

添加对以下内容的支持:

  • 体重秤
  • bmp
  • 电脑
  • 纳米
  • 生的
  • 蒂夫
  • gif(写)

您可以通过以下方式查看支持的格式列表:

     for(String format : ImageIO.getReaderFormatNames())
        System.out.println(format);
Run Code Online (Sandbox Code Playgroud)

请注意,您只需将 jar(例如 jai-imageio-core-1.3.1.jar)放入类路径中即可使其工作。

其他为图像类型添加额外支持的项目包括: