[JAVA] Write byte array image data to outputstream using ImageIO

Introduction

When I tried to put a byte array in outputStream using ImageIO, I got stuck in various ways, so I will write it as a memo.

For the time being, somehow the sauce

    public void writeOutputStream(byte[] byteArray, OutputStream outputStream, String fileFormat) throws IOException {
        ByteArrayInputStream imageInput = new ByteArrayInputStream(byteArray);
        BufferedImage buffer = ImageIO.read(imageInput);

        ImageWriter writer = null;
        Iterator<ImageWriter> iter = ImageIO.getImageWritersByFormatName(fileFormat);
        if (iter.hasNext()) {
            writer = iter.next();
        }

        ImageWriteParam param = writer.getDefaultWriteParam();
        if (param.canWriteCompressed() && fileFormat.equals("jpg")) {
            param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
            param.setCompressionQuality(0.5f);
        }

        ImageOutputStream ios = ImageIO.createImageOutputStream(outputStream);
        writer.setOutput(ios);
        IIOImage iioImage = new IIOImage(buffer, null, null);
        writer.write(null, iioImage, param);
    }

Source description

I don't think the explanation is so necessary, but I will explain the points that are likely to get caught.

Argument assumptions

The story of ImageWriteParam

This time, I had to use ImageWriteParam because I was tasked with compressing the image. This is the part that I got the most out of this time, and the compression conditions are strict and only JPEG or GIF is possible, and PNG will cause an Exception. It is possible to forcibly compress PNG using a JPEG writer, but unfortunately it was not useful.

So, this time I decided to put the judgment of param.canWriteCompressed () && fileFormat.equals ("jpg "). canWriteCompressed changes depending on the type of ImageWriteParam, and as described above, when you extract from getImageWritersByFormatName, JPEG and GIF will be returned as true, and PNG will be returned as false. I also added JPG judgment (actually "jpeg" is also required), but in the case of GIF images, it seems that an Exception will occur if you also specify setCompressionType, but I was not sure what to specify. So I put it in.

JavaDoc https://docs.oracle.com/javase/jp/7/api/javax/imageio/ImageWriteParam.html

Writing story

ImageWrite is used for writing, but when the Object to be actually written is setOutput, it must be converted to a specific format. Since the ImageIO class has a create method, you can use it to convert it to an ImageOutputStream, but I haven't investigated which class is writable. For the time being, there is no problem if you convert it with this, but it is troublesome if ImageOutputStream is not allowed in the writer extracted from getImageWritersByFormatName.

As long as I tried it with PNG, JPEG, and GIF, everything was fine, so I don't think it's a problem for everyday use. If you want to create your own ImageWrite, be aware that it may hurt if you don't think about it properly.

If you want to write directly to OutputStream without compression or optimization processing, you can do it quickly with ImageIO.write, so you can write to Allowed OutputStream without the procedure of conversion.

Recommended Posts

Write byte array image data to outputstream using ImageIO
To write Response data directly in Spring
How to implement image posting using rails
[Rails] How to handle data using enum
Write to a file using ShiftJIS-Read a file (Kotlin / JVM)
Flow to implement image posting function using ActiveStorage
How to create hierarchical category data using ancestry
Push the image to docker hub using Jib