ImageIO.read无法读取ByteArrayInputStream(图像处理)

ImageIO.read can't read ByteArrayInputStream (image processing)

我正在尝试读入图像文件,将其转换为字节数组,处理各个字节,然后将其转换回图像文件并导出。

我已经尝试处理它,但似乎 ImageIO.read 无法读取 ByteInputArrayStream - 它 returns 为空。

这是我到目前为止尝试过的方法(以及引发错误的行)

public static void RGBToGrayManual2(BufferedImage original) {
    byte[] pixels = ((DataBufferByte) original.getRaster().getDataBuffer()).getData();

    /*
     *  Code to process pixels
     */

    ByteArrayInputStream grayscaleByteInputStream = new ByteArrayInputStream(pixels);
    BufferedImage convertedGrayscale = null;


    try {
        // below line throws the error
        convertedGrayscale = ImageIO.read(grayscaleByteInputStream);

        ImageIO.write(convertedGrayscale, "jpg", new File("converted-grayscale-002.jpg"));
    } catch (IOException e) {
        System.err.println("IOException: " + e);
    }   
}

以及错误信息

Exception in thread "main" java.lang.IllegalArgumentException: image == null! at javax.imageio.ImageTypeSpecifier.createFromRenderedImage(ImageTypeSpecifier.java:925) at javax.imageio.ImageIO.getWriter(ImageIO.java:1591) at javax.imageio.ImageIO.write(ImageIO.java:1520) at project2.ImageProcessing.RGBToGrayManual2(ImageProcessing.java:252) at project2.ImageProcessing.main(ImageProcessing.java:284)

我也看过类似的 post - Null returned from ImageIO.read(new ByteArrayInputStream(bs)); - 接受的答案似乎表明这是编码问题。

我看过另一个 post - Which Java library provides base64 encoding/decoding? - 来解码字节数组,但我认为我做的不对。

这是我尝试过的:

String encodedPixelsString = DatatypeConverter.printBase64Binary(pixels);
byte[] decodedPixelsString = DatatypeConverter.parseBase64Binary(encodedPixelsString);
ByteArrayInputStream pixelsStreamInputStream = new ByteArrayInputStream(decodedPixelsString);

并传入解码数组的 ByteArrayInputStream 作为参数

    convertedGrayscale = ImageIO.read(pixelStreamInputStream);

但是它产生了完全相同的错误消息。

我对解决这个问题的两个可能方向的想法 - 但我不确定细节:

  1. ImageIO.read方法找出问题
  2. 尝试以不同的方式公开图像文件的字节数组

这是我们必须要做的作业,但我以前从未接触过图像处理,因此,我有点不知所措。我真的很感激任何指点

首先,异常是不是来自ImageIO.read(...)方法。它 returns null,这是应该的。但是,当您使用 null 图像调用 ImageIO.write(...) 时,会出现异常。

现在,您输入的 ImageIO.read(...) returns null 的原因仅仅是因为 ImageIO 读取和写入图像 from/to 文件格式。您的 pixels byte 数组不是文件格式,它是原始像素数据(而且,不,这与 Base64 或其他字符串编码无关)。

现在,假设你的 pixel 数组是 8 bits/pixel 灰度格式(重要的是,如果这个假设是错误的,下面的代码将不起作用,但你没有提供足够的信息供其他人确定这一点,因此您可能需要修改代码以适合您的数据),您可以轻松地重新创建 BufferedImage:

byte[] pixels = ((DataBufferByte) original.getRaster().getDataBuffer()).getData();

/*
 *  Code to process pixels (just as before)
 */

// Replace the ImageIO.read invocation with the following code
// Note that *pixels* must be in 8 bits/pixel (grayscale) for this to work,
// it is not cheating! :-)
BufferedImage convertedGrayscale = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
convertedGrayScale.getRaster().setDataElements(0, 0, width, height, pixels);

try {
    ImageIO.write(convertedGrayscale, "jpg", new File("converted-grayscale-002.jpg"));
} 
catch (IOException e) {
    System.err.println("IOException: " + e);
}