【问题标题】:ImageIO.read can't read ByteArrayInputStream (image processing)ImageIO.read 无法读取 ByteArrayInputStream(图像处理)
【发布时间】:2016-03-22 08:44:44
【问题描述】:

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

我已经尝试过处理它,但似乎 ImageIO.read 无法读取 ByteInputArrayStream - 它返回 null。

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

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);
    }   
}

还有错误提示

线程“主”java.lang.IllegalArgumentException 中的异常:图像 == 空!在 javax.imageio.ImageTypeSpecifier.createFromRenderedImage(ImageTypeSpecifier.java:925) 在 javax.imageio.ImageIO.getWriter(ImageIO.java:1591) 在 javax.imageio.ImageIO.write(ImageIO.java:1520) 在 project2.ImageProcessing.RGBToGrayManual2(ImageProcessing.java:252) 在 project2.ImageProcessing.main(ImageProcessing.java:284)

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

我查看了另一篇帖子 - 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. 尝试以不同的方式公开图像文件的字节数组

这是我们必须完成的任务,但我以前从未从事过图像处理工作,因此,我不知道该怎么做。我真的很感激任何指针

【问题讨论】:

  • 您要将颜色转换为灰色吗?
  • @BahramdunAdil 是的 - 但我不允许使用任何 Java 的类方法(如 BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY); ),我必须实现一个方法来做到这一点。
  • 在异常中它非常清楚地表明您的图像(convertedGrayscale)为空
  • @BahramdunAdil convertedGrayscale = ImageIO.read(grayscaleByteInputStream); - 此行引发错误。但是,grayscaleByteInputStream 是正确的,绝对不是 null。
  • 确定原件有数据吗?

标签: java javax.imageio


【解决方案1】:

首先,ImageIO.read(...) 方法中的例外不是。它应该返回null。但是,当您使用 null 图像调用 ImageIO.write(...) 时,会发生异常。

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

现在,假设您的 pixel 数组是 8 位/像素灰度格式(重要的是,如果此假设错误,以下代码将不起作用,但您没有提供足够的信息供其他人确定这一点,因此您可能需要修改代码以适合您的数据),您可以轻松地重新创建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);
}

【讨论】:

  • @heraldK 我实际上是在考虑这些方面的东西——所以我想用它作为输入来构造一个 File 对象,但我不知道该怎么做。您的假设是正确的 :) 像素数据是 8 位/像素。但是,我不能用 TYPE_BYTE_GRAY 构造一个新的 BufferedImage - 我们的任务是编写一个在像素级别上处理图像的方法。
  • @heraldK 对不起,我忘了补充——如果你能指出如何从 ByteArrayInputStream 构造一个 File 对象以用作 ImageIO.read() 方法的参数,它可以工作,我会将此答案标记为正确。谢谢:)
  • @CodeApprentice ??那为什么呢?您的问题是在 处理后读取图像,我解决了这个问题。您不应该也不能使用ImageIO.read() 阅读此内容,因为它是原始像素数据。处理部分我留给你,这是一个作业。但是,当您使用我的答案中的代码构造新的BufferedImage 时,您可以将该图像传递给ImageIO.write(convGray, "JPEG", new File(...))
  • @heraldK 啊——我明白了!所以这里的思路是构造一个TYPE_BYTE_GRAY类型的新图像,然后将像素设置为处理后的像素。我误解了。谢谢你的耐心! :)
猜你喜欢
  • 1970-01-01
  • 2011-01-25
  • 1970-01-01
  • 2022-10-14
  • 1970-01-01
  • 1970-01-01
  • 2015-07-26
  • 1970-01-01
  • 2010-12-04
相关资源
最近更新 更多