web-dev-qa-db-fra.com

Comment redimensionner une image avec Java?

J'ai besoin de redimensionner les fichiers PNG, JPEG et GIF. Comment puis-je faire cela en utilisant Java?

119
pbreault

Après avoir chargé l'image, vous pouvez essayer:

BufferedImage createResizedCopy(Image originalImage, 
            int scaledWidth, int scaledHeight, 
            boolean preserveAlpha)
    {
        System.out.println("resizing...");
        int imageType = preserveAlpha ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
        BufferedImage scaledBI = new BufferedImage(scaledWidth, scaledHeight, imageType);
        Graphics2D g = scaledBI.createGraphics();
        if (preserveAlpha) {
            g.setComposite(AlphaComposite.Src);
        }
        g.drawImage(originalImage, 0, 0, scaledWidth, scaledHeight, null); 
        g.dispose();
        return scaledBI;
    }
84
Burkhard

FWIW Je viens de publier (Apache 2, hébergé sur GitHub) une simple bibliothèque de dimensionnement d’images pour Java appelée imgscalr (disponible sur Maven central ).

La bibliothèque met en œuvre différentes approches d’échelle d’image (y compris l’approche incrémentielle de Chris Campbell avec quelques améliorations mineures) et choisira l’approche la plus optimale pour vous si vous le demandez, ou vous donnera l’apparence la plus rapide ou la plus jolie (si vous le souhaitez. demander pour cela).

L'utilisation est simple, juste un tas de méthodes statiques. Le cas d'utilisation le plus simple est:

BufferedImage scaledImage = Scalr.resize(myImage, 200);

Toutes les opérations conservent les proportions d'origine de l'image. Dans ce cas, vous demandez à imgscalr de redimensionner votre image dans des limites de 200 pixels de large et 200 pixels de haut. Par défaut, cette option sélectionne automatiquement l'approche la plus belle et la plus rapide 't pas spécifié.

Je me rends compte au départ que cela ressemble à de la promotion personnelle (c’est vrai), mais j’ai passé assez de temps à googler exactement sur le même sujet et à proposer des résultats/approches/pensées/suggestions différents, puis j’ai décidé Une implémentation simple qui tiendrait compte de 80 à 85% des cas d’utilisation où vous avez une image et souhaitez probablement une vignette - le plus rapidement possible ou le plus beau possible (pour ceux qui ont essayé, vous remarquerez faire un Graphics.drawImage même avec une interpolation BICUBIC en une image assez petite, cela ressemble toujours à des ordures).

177
Riyad Kalla

Thumbnailator est une bibliothèque de redimensionnement d'image open source pour Java avec une interface fluide, distribuée sous la licence MIT.

J'ai écrit cette bibliothèque parce que créer des miniatures de haute qualité en Java peut être étonnamment difficile et que le code obtenu peut être assez compliqué. Avec Thumbnailator, il est possible d'exprimer des tâches assez compliquées en utilisant une simple API fluide.

Un exemple simple

Pour un exemple simple, prendre une image et la redimensionner à 100 x 100 (en préservant le format de l'image d'origine), puis l'enregistrer dans un fichier peut être réalisée en une seule déclaration:

Thumbnails.of("path/to/image")
    .size(100, 100)
    .toFile("path/to/thumbnail");

Un exemple avancé

L'exécution de tâches de redimensionnement complexes est simplifiée avec l'interface fluide de Thumbnailator.

Supposons que nous voulions faire ce qui suit:

  1. prendre les images dans un répertoire et,
  2. redimensionnez-les à 100 x 100, avec le format de l'image d'origine,
  3. enregistrez-les tous au format JPEG avec des paramètres de qualité de 0.85,
  4. où les noms de fichiers sont pris à partir de l'original avec thumbnail. ajouté au début

Traduit en Thumbnailator, nous pourrions effectuer ce qui précède avec ce qui suit:

Thumbnails.of(new File("path/to/directory").listFiles())
    .size(100, 100)
    .outputFormat("JPEG")
    .outputQuality(0.85)
    .toFiles(Rename.PREFIX_DOT_THUMBNAIL);

Une note sur la qualité et la vitesse de l'image

Cette bibliothèque utilise également la méthode mise à l'échelle bilinéaire progressive mise en évidence dans Filthy Rich Clients par Chet Haase et Romain Guy pour générer des vignettes de haute qualité tout en garantissant des performances d'exécution acceptables.

49
coobird

Vous n'avez pas besoin d'une bibliothèque pour faire cela. Vous pouvez le faire avec Java lui-même.

Chris Campbell a rédigé un excellent et détaillé exposé sur le redimensionnement des images - voir cet article .

Chet Haase et Romain Guy ont également une description détaillée et très informative de la mise à l'échelle des images dans leur livre, Filthy Rich Clients

11
David Koelle

Java Advanced Imaging est maintenant open source et fournit les opérations dont vous avez besoin.

10
Ken Gentle

Si vous avez affaire à de grandes images ou si vous voulez un résultat agréable, ce n'est pas une tâche facile en Java. Le faire simplement via une opération de redimensionnement via Graphics2D ne créera pas une vignette de haute qualité. Vous pouvez le faire en utilisant JAI, mais cela demande plus de travail que vous ne l'imaginiez pour obtenir quelque chose de beau et JAI a la fâcheuse habitude de détruire votre JVM avec des erreurs OutOfMemory. 

Je suggère d'utiliser ImageMagick en tant qu'exécutable externe si vous pouvez vous en tirer. C'est simple à utiliser et il fait le travail correctement pour que vous n'ayez pas à le faire. 

9
Joel Carranza

Si, ayant imagemagick installé sur votre machine est une option, je recommande im4Java . C'est une couche d'abstraction très mince sur l'interface de ligne de commande, mais fait très bien son travail.

4
naltatis

Vous pouvez essayer d'utiliser GraphicsMagick Image Processing System avec im4Java comme interface standard pour Java.

GraphicsMagick présente de nombreux avantages, mais un pour tous:

  • GM est utilisé pour traiter des milliards de fichiers .__ sur les plus grands sites photo au monde (par exemple Flickr et Etsy).
2
kajo

L'API Java ne fournit pas de fonctionnalité de redimensionnement standard pour les images et la dégradation de la qualité d'image.

A cause de cela, j'ai essayé d'utiliser cvResize à partir de JavaCV mais cela semble poser problème.

J'ai trouvé une bonne bibliothèque pour le redimensionnement d'image: ajoutez simplement la dépendance pour "Java-image-scaling" dans votre pom.xml. 

<dependency>
    <groupId>com.mortennobel</groupId>
    <artifactId>Java-image-scaling</artifactId>
    <version>0.8.6</version>
</dependency>

Dans le référentiel Maven, vous aurez la version récente pour cela.

Ex. Dans votre programme Java

ResampleOp resamOp = new ResampleOp(50, 40);
BufferedImage modifiedImage = resamOp.filter(originalBufferedImage, null);
2
Ruju

Vous pouvez utiliser Marvin (framework de traitement d’images Java pur) pour ce type d’opération: http://marvinproject.sourceforge.net

Plug-in Scale: http://marvinproject.sourceforge.net/en/plugins/scale.html

1
Robert

Image Magick a été mentionné. Il existe un projet frontal JNI appelé JMagick. Ce n'est pas un projet particulièrement stable (et Image Magick elle-même est connue pour beaucoup changer et même briser la compatibilité). Cela dit, nous avons utilisé JMagick et une version compatible d’Image Magick dans un environnement de production pour effectuer une mise à l’échelle à un taux de latence élevé et à haut débit. La vitesse était nettement meilleure qu'avec une bibliothèque graphique entièrement en Java que nous avions précédemment essayée.

http://www.jmagick.org/index.html

1
Jice

Utilisez simplement la réponse de Burkhard, mais ajoutez cette ligne après la création du graphique:

    g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);

Vous pouvez également définir la valeur sur BICUBIC, cela produira une image de meilleure qualité mais coûtera plus cher. Il existe d’autres astuces de rendu que vous pouvez définir, mais j’ai constaté que l’interpolation produisait l’effet le plus notable . N'oubliez pas que si vous souhaitez effectuer un zoom avant, le code Java sera probablement très lent. Je trouve que les images plus grandes commencent à produire un décalage d'environ 300%, même lorsque tous les indicateurs de rendu sont configurés pour optimiser la vitesse.

1

Il s'avère que l'écriture d'un détartreur performant n'est pas anodine. Je l'ai fait une fois pour un projet open source: ImageScaler .

En principe, 'Java.awt.Image # getScaledInstance (int, int, int)' ferait également l'affaire, mais il existe un bogue méchant avec ceci - référez-vous à mon lien pour plus de détails.

1
aanno

Si vous ne voulez pas importer imgScalr like @Riyad Kalla réponse ci-dessus que j'ai aussi testé fonctionne bien, vous pouvez le faire Tiré de Peter Walser answer @Peter Walser sur un autre problème:

 /**
     * utility method to get an icon from the resources of this class
     * @param name the name of the icon
     * @return the icon, or null if the icon wasn't found.
     */
    public Icon getIcon(String name) {
        Icon icon = null;
        URL url = null;
        ImageIcon imgicon = null;
        BufferedImage scaledImage = null;
        try {
            url = getClass().getResource(name);

            icon = new ImageIcon(url);
            if (icon == null) {
                System.out.println("Couldn't find " + url);
            }

            BufferedImage bi = new BufferedImage(
                    icon.getIconWidth(),
                    icon.getIconHeight(),
                    BufferedImage.TYPE_INT_RGB);
            Graphics g = bi.createGraphics();
            // Paint the Icon to the BufferedImage.
            icon.paintIcon(null, g, 0,0);
            g.dispose();

            bi = resizeImage(bi,30,30);
            scaledImage = bi;// or replace with this line Scalr.resize(bi, 30,30);
            imgicon = new ImageIcon(scaledImage);

        } catch (Exception e) {
            System.out.println("Couldn't find " + getClass().getName() + "/" + name);
            e.printStackTrace();
        }
        return imgicon;
    }

 public static BufferedImage resizeImage (BufferedImage image, int areaWidth, int areaHeight) {
        float scaleX = (float) areaWidth / image.getWidth();
        float scaleY = (float) areaHeight / image.getHeight();
        float scale = Math.min(scaleX, scaleY);
        int w = Math.round(image.getWidth() * scale);
        int h = Math.round(image.getHeight() * scale);

        int type = image.getTransparency() == Transparency.OPAQUE ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;

        boolean scaleDown = scale < 1;

        if (scaleDown) {
            // multi-pass bilinear div 2
            int currentW = image.getWidth();
            int currentH = image.getHeight();
            BufferedImage resized = image;
            while (currentW > w || currentH > h) {
                currentW = Math.max(w, currentW / 2);
                currentH = Math.max(h, currentH / 2);

                BufferedImage temp = new BufferedImage(currentW, currentH, type);
                Graphics2D g2 = temp.createGraphics();
                g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
                g2.drawImage(resized, 0, 0, currentW, currentH, null);
                g2.dispose();
                resized = temp;
            }
            return resized;
        } else {
            Object hint = scale > 2 ? RenderingHints.VALUE_INTERPOLATION_BICUBIC : RenderingHints.VALUE_INTERPOLATION_BILINEAR;

            BufferedImage resized = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
            Graphics2D g2 = resized.createGraphics();
            g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
            g2.drawImage(image, 0, 0, w, h, null);
            g2.dispose();
            return resized;
        }
    }
0
shareef

vous pouvez utiliser le produit populaire suivant: thumbnailator

0
gstackoverflow

J'ai développé une solution avec les classes disponibles gratuitement (AnimatedGifEncoder, GifDecoder et LWZEncoder) disponibles pour la gestion des animations GIF.
Vous pouvez télécharger le fichier jgifcode et exécuter la classe GifImageUtil . Link: http://www.jgifcode.com

0
Rohit Tiwari