ImageIO 中的异常 "java.lang.IllegalArgumentException: image == null!"

Exception "java.lang.IllegalArgumentException: image == null!" in ImageIO

我正在尝试从字节数组写入 png 文件。

我的应用程序抛出以下异常 "java.lang.IllegalArgumentException: image == null!" in ImageIO

我使用随机字节数组测试了我的解决方案,如下面的代码片段所示,但仍然抛出异常。

你能帮我确定为什么会被抛出吗?

    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.io.IOException;
    import java.util.Random;
    import javax.imageio.ImageIO;
    public class Main {

        public static void main(String[] args) throws IOException {
            String fn = new String("C:\Users\frogwine\Desktop\P1.png");

            byte [] data = new byte[256];

            Random r = new Random();
            r.nextBytes(data);
            ByteArrayInputStream bis = new ByteArrayInputStream(data);
            ByteArrayInputStream input_stream= new ByteArrayInputStream(data);
            BufferedImage final_buffered_image = ImageIO.read(input_stream);
            ImageIO.write(final_buffered_image , "png", new File(fn) );
        }


    }

堆栈跟踪:

    "C:\Program Files\Java\jdk-13.0.1\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2019.3\lib\idea_rt.jar=57315:C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2019.3\bin" -Dfile.encoding=UTF-8 -classpath C:\Users\frogwine\Documents\deneme\out\production\deneme com.berk.Main
    Exception in thread "main" java.lang.IllegalArgumentException: image == null!
        at java.desktop/javax.imageio.ImageTypeSpecifier.createFromRenderedImage(ImageTypeSpecifier.java:925)
        at java.desktop/javax.imageio.ImageIO.getWriter(ImageIO.java:1608)
        at java.desktop/javax.imageio.ImageIO.write(ImageIO.java:1540)
        at com.berk.Main.main(Main.java:23)

    Process finished with exit code 1

嗯,这并不奇怪。来自 ImageIO.read 文档:

If no registered ImageReader claims to be able to read the resulting stream, null is returned.

将随机字节写入数组不会创建任何格式的有效图像数据,因为图像格式具有至少由 header 组成的标准结构。为此,ImageIO.read returns null.

正如 Leo 还提到的,只是将随机字节传递给 ImageIO.read 方法,您无法获得随机图像。您将获得空图像,当您将其传递给 write 方法时,它将抛出此 IllegalArgumentException。

相反,您可以创建具有预定义宽度和高度的空图像并设置 RGB 颜色值以获得如下随机图像。

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
public class Main {

    public static void main(String[] args) throws IOException {
        String fn = new String("C:\Users\frogwine\Desktop\P1.png");
        ImageIO.write(generateRandomImage(300) , "png", new File(fn) );
    }


    public static BufferedImage generateRandomImage(int numOfPixels) {
        final double ASPECT_RATIO = 4.0 / 3.0;
        int width = 0;
        int height = 0;
        byte[] rgbValue = new byte[3];
        BufferedImage image = null;
        SecureRandom random = null;

        try {
            random = SecureRandom.getInstance("SHA1PRNG");

            width = (int) Math.ceil(Math.sqrt(numOfPixels * ASPECT_RATIO));
            height = (int) Math.ceil(numOfPixels / (double) width);

            image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            for (int x = 0; x < width; x++) {
                for (int y = 0; y < height; y++) {
                    random.nextBytes(rgbValue);
                    image.setRGB(x, y,
                            byteToInt(rgbValue[0]) + (byteToInt(rgbValue[1]) << 8) + (byteToInt(rgbValue[2]) << 16));
                }
            }

            return image;
        } catch (NoSuchAlgorithmException nsaEx) {
            nsaEx.printStackTrace();
        }
        return null;
    }

    public static int byteToInt(int b) {
        int i = b;
        if (i < 0) {
            i = i + 256;
        }
        return i;
    }