[JAVA] Écrire des données d'image de tableau d'octets dans le flux de sortie à l'aide d'ImageIO

introduction

Quand j'ai essayé de mettre un tableau d'octets dans outputStream en utilisant ImageIO, je suis resté bloqué de différentes manières, donc je l'écrirai sous forme de mémo.

Pour le moment, en quelque sorte la source

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

Description de la source

Je ne pense pas que l'explication soit tellement nécessaire, mais je vais expliquer les points qui risquent de se faire prendre.

Hypothèse d'argument

L'histoire d'ImageWriteParam

Cette fois, j'ai dû utiliser ImageWriteParam car j'étais chargé de compresser l'image. C'est la partie qui convient le mieux cette fois-ci, et les conditions de compression sont strictes et seul JPEG ou GIF est possible, et PNG provoquera une exception. Il est possible de forcer la compression PNG à l'aide d'un graveur JPEG, mais malheureusement, il n'était pas utilisable.

Donc, cette fois, j'ai décidé de mettre le jugement de param.canWriteCompressed () && fileFormat.equals (" jpg "). canWriteCompressed change en fonction du type de ImageWriteParam, et comme décrit ci-dessus, lors de l'extraction de getImageWritersByFormatName, JPEG et GIF sont renvoyés comme vrai et PNG est retourné comme faux. J'ai également ajouté un jugement JPG (en fait "jpeg" est également requis), mais dans le cas des images GIF, il semble qu'une exception se produira si vous spécifiez également setCompressionType, mais je ne savais pas quoi spécifier. Alors je l'ai mis.

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

Écrire une histoire

ImageWrite est utilisé pour l'écriture, mais lorsque l'objet à écrire est setOutput, il doit être converti dans un format spécifique. Étant donné que la classe ImageIO a une méthode de création, vous pouvez l'utiliser pour la convertir en ImageOutputStream, mais je n'ai pas recherché quelle classe est accessible en écriture. Pour le moment, il n'y a pas de problème si vous le convertissez avec cela, mais il est gênant si ImageOutputStream n'est pas autorisé dans l'enregistreur extrait de getImageWritersByFormatName.

Tant que je l'ai essayé avec PNG, JPEG et GIF, tout allait bien, donc je ne pense pas que ce soit un problème pour un usage quotidien. Si vous souhaitez créer votre propre ImageWrite, sachez que cela peut faire mal si vous n'y réfléchissez pas correctement.

Si vous souhaitez écrire directement dans OutputStream sans compression ou traitement d'optimisation, vous pouvez le faire rapidement avec ImageIO.write, de sorte que vous pouvez écrire dans Allowed OutputStream sans la procédure de conversion.

Recommended Posts

Écrire des données d'image de tableau d'octets dans le flux de sortie à l'aide d'ImageIO
Pour écrire des données de réponse directement dans Spring
Pour implémenter la publication d'images à l'aide de rails
Écrire dans un fichier en utilisant ShiftJIS ・ Lire un fichier (Kotlin / JVM)
Flux pour implémenter la fonction de publication d'images à l'aide d'ActiveStorage
Comment créer des données de catégorie hiérarchique à l'aide de l'ascendance
Poussez l'image vers le hub docker à l'aide de Jib