Limiter la taille et le poids d'une image

Soyez le premier à donner votre avis sur cette source.

Snippet vu 1 720 fois


Contenu du snippet

Lors du chargement d'une image sur un site internet il est courant de devoir respecter un certain nombre de contraintes, telles que la taille ou le poids d'une image.

La méthode utilitaire ci-dessous permet de copier une image quelconque pour obtenir un fichier JPG satisfaisant les limites données en paramètres.

Exemple :

ImageUtil.copyImageWithLimitations(
    new File("C:/input.png"),  // le fichier d'origine (png, jpg, gif, bmp...)
    new File("C:/output.jpg"), // le fichier résultat
    200, 200, // les dimensions maximales de l'image (200x200 px)
    500_000); // le poids maximal du fichier cible (50 Ko)

Dans un premier temps, la taille est redimensionnée afin d'obtenir l'image la plus grande possible (mais jamais plus que la taille d'origine).

Dans un second temps, le fichier est enregistré avec une qualité maximale et si le poids du fichier est trop important, la qualité de l'image est diminuée jusqu'à atteindre une taille suffisament petite.

Le code ci-dessous est compatible Java 7 (ou plus).

package util;

import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.plugins.jpeg.JPEGImageWriteParam;
import javax.imageio.stream.FileImageOutputStream;

/**
 * @author KX
 */
public class ImageUtil {

    /**
     * Copy an image file with size and length limitations.
     * 
     * @param originalFile
     *            a File to read from (PNG, JPG, GIF, BMP, WBMP formats)
     * @param destinationFile
     *            a File to be written to (JPG format)
     * @param maxWidth
     *            maximum width of the image (in pixels)
     * @param maxHeight
     *            maximum height of the image (in pixels)
     * @param maxLength
     *            maximum length of the file (in bytes)
     * @return length of the destinationFile (0 if parameters are too limiting and so file was not written)
     * @throws IOException
     *             if an I/O error occurs.
     */
    public static long copyImageWithLimitations(File originalFile, File destinationFile, int maxWidth, int maxHeight, long maxLength) throws IOException {
        BufferedImage originalImage = ImageIO.read(originalFile);
        int originalWidth = originalImage.getWidth();
        int originalHeight = originalImage.getHeight();
        double ratioWidth = (double) maxWidth / originalWidth;
        double ratioHeight = (double) maxHeight / originalHeight;
        double ratio = Math.min(1, Math.min(ratioWidth, ratioHeight));
        int resizedWidth = (int) (ratio * originalWidth);
        int resizedHeight = (int) (ratio * originalHeight);
        BufferedImage resizedImage = new BufferedImage(resizedWidth, resizedHeight, BufferedImage.TYPE_INT_RGB);
        Graphics2D graphics = resizedImage.createGraphics();
        graphics.drawImage(originalImage, 0, 0, resizedWidth, resizedHeight, null);
        graphics.dispose();
        for (float quality = 1f; quality > 0; quality -= 0.05) {
            try (FileImageOutputStream out = new FileImageOutputStream(destinationFile)) {
                JPEGImageWriteParam jpegParams = new JPEGImageWriteParam(null);
                jpegParams.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
                jpegParams.setCompressionQuality(quality);
                ImageWriter writer = ImageIO.getImageWritersByFormatName("jpg").next();
                writer.setOutput(out);
                writer.write(null, new IIOImage(resizedImage, null, null), jpegParams);
            }
            long destinationLength = destinationFile.length();
            if (destinationLength <= maxLength)
                return destinationLength;
            destinationFile.delete();
        }
        return 0;
    }
}

Compatibilité : 1

A voir également

Ajouter un commentaire

Commentaires

Commenter la réponse de KX

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.