1

I'm trying to write a png file from a bytes array.

My application is throwing the following exception "java.lang.IllegalArgumentException: image == null!" in ImageIO

I tested my solution using a random bytes array as you can see in the code snippet below, but the exception still being thrown.

Can you help me to identify why is it being thrown ?

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


    }

Stacktrace:

    "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
eHayik
  • 2,981
  • 1
  • 21
  • 33
  • Does this answer your question? [java.lang.IllegalArgumentException: input == null! when using ImageIO.read to load image as bufferedImage](https://stackoverflow.com/questions/15424834/java-lang-illegalargumentexception-input-null-when-using-imageio-read-to-lo) – Amongalen Dec 09 '19 at 11:36
  • @Amongalen could you suggest an example for usage? –  Dec 09 '19 at 11:39
  • 1
    Not related to your problem, but you really should not do things like `new String("C:\\Users\\frogwine\\Desktop\\P1.png")`, literals enclosed in double quotes are already strings, so no need to create another copy of it. You may also want to familiarize yourself with common Java coding conventions, because snake_case is not commonly used in Java, making your code harder to read for Java programmers. – Mark Rotteveel Dec 09 '19 at 18:47

2 Answers2

4

Well that's no surprise. From the ImageIO.read documentation:

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

Writing random bytes to an array is not going to create valid image data in any format, because image formats have a standard structure that consists, at the very least, of a header. For this reason, ImageIO.read returns null.

Leo Aso
  • 11,898
  • 3
  • 25
  • 46
  • I got it, but why we have some tutorials like this [link]https://www.codespeedy.com/convert-byte-array-to-image-in-java/ and more [link]https://www.tutorialspoint.com/How-to-convert-Byte-Array-to-Image-in-java –  Dec 09 '19 at 11:51
  • 1
    Those tutorials aren't trying to write random bytes; the bytes were read from an existing image. – Leo Aso Dec 09 '19 at 15:20
1

As Leo also mentioned just passing random bytes to ImageIO.read method, you cannot get a random image. You will get null image and when you passed it to write method it will throw this IllegalArgumentException.

Instead you can create empty image with predefined width and height and set RGB color values to get random image as below.

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;
    }
lakshman
  • 2,641
  • 6
  • 37
  • 63