puisque vous avez demandé une bibliothèque, la vraie réponse est ici: stackoverflow.com/questions/244164/… . C'est beaucoup plus facile à utiliser que le code dans la réponse acceptée;)
Artur Gajowy
Je ne suis pas d'accord sur la partie bibliothèque: Graphics2D fait partie de la bibliothèque awt et est open source. Pour la dernière partie (open source), je ne suis pas sûr à 100%, mais qui regarderait le code awt de toute façon?
J'ai trouvé que cette technique crée une image dont la qualité n'est pas suffisante pour mes besoins.
morgancodes
1
Image.getScaledInstance (largeur, hauteur, indices) fera-t-il également l'affaire?
codeplay
1
la vérification de preserveAlpha est-elle dans le mauvais sens (pour l'imageType)?
Thilo
Je suis d'accord avec @morgancodes. La qualité de l'image est bien pire que ce que vous obtenez avec, par exemple, l'aperçu OS X lors du redimensionnement aux mêmes dimensions. J'essaierai quelques bibliothèques open-source pour voir si elles s'en tirent mieux.
Thilo
1
"Je vais essayer des bibliothèques open-source pour voir si elles s'en tirent mieux." +1 pour imgscalr de la réponse de @ RiyadKalla.
Thilo
182
FWIW Je viens de publier (Apache 2, hébergé sur GitHub) une simple bibliothèque de mise à l'échelle d'image pour Java appelée imgscalr (disponible sur Maven central ).
La bibliothèque met en œuvre plusieurs approches différentes de la mise à l'échelle de l'image (y compris l'approche incrémentielle de Chris Campbell avec quelques améliorations mineures) et choisira soit l'approche la plus optimale pour vous si vous le lui demandez, soit vous donnera la plus rapide ou la meilleure apparence (si vous demandez-le).
L'utilisation est extrêmement simple, juste un tas de méthodes statiques. Le cas d'utilisation le plus simple est:
Toutes les opérations conservent les proportions d'origine de l'image, donc dans ce cas, vous demandez à imgscalr de redimensionner votre image dans des limites de 200 pixels de large et 200 pixels de haut et par défaut, il sélectionnera automatiquement la meilleure approche et la plus rapide pour cela depuis 't spécifié.
Je me rends compte dès le départ que cela ressemble à de l'auto-promotion (c'est le cas), mais j'ai passé ma juste part de temps à googler exactement le même sujet et j'ai continué à proposer des résultats / approches / pensées / suggestions différents et j'ai décidé de m'asseoir et d'écrire un implémentation simple qui répondrait à 80 à 85% des cas d'utilisation où vous avez une image et que vous voulez probablement une vignette pour celle-ci - soit aussi vite que possible ou aussi belle que possible (pour ceux qui ont essayé, vous remarquerez faire un Graphics.drawImage même avec une interpolation BICUBIC vers une image suffisamment petite, cela ressemble toujours à une poubelle).
Riyad, j'ai aimé utiliser Scalr. Je suis curieux de savoir, comment avez-vous fini par choisir une API avec toutes les méthodes statiques? J'avais écrit une API similaire qui était plus proche d'un constructeur. Comme new ImageScaler(img).resizeTo(...).rotate(...).cropTo(...).toOutputBuffer(). J'aime aussi ton chemin et je pense que c'est plus simple.
Amir Raminfar
4
Amir, le modèle de constructeur fonctionne à merveille pour ces types de bibliothèques également, il m'est arrivé de suivre l'approche de la méthode statique parce que je pensais que c'était un poil plus facile à suivre pour les nouveaux utilisateurs et le modèle d'utilisation que j'attendais d'imgscalr (à l'origine seules les méthodes de redimensionnement uniques) n'ont pas bénéficié d'un état de maintien d'instance (l'instance du générateur). J'ai donc économisé sur l'instanciation de l'objet et suis allé avec les méthodes statiques. J'ai pris une position ferme contre la création d'objets à l'intérieur d'imgscalr dans tous les endroits où je peux l'éviter. Les deux approches fonctionnent très bien cependant.
Riyad Kalla
5
+1 pour avoir rendu cela disponible sur le référentiel central Maven!
Grilse
Quelle est cette classe BufferedImage, pourquoi Android Studio ne la trouve pas? @Riyad Kalla
Milad
3
@ xe4me BufferedImage est une classe du J2SE JDK (faisant partie du framework Java2D) utilisée pour représenter des données de pixels brutes et non compressées. Il n'est pas disponible sur Android, Android fournit ses propres classes pour travailler avec des données d'image.
Riyad Kalla
54
Thumbnailator est une bibliothèque de redimensionnement d'images 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 vignettes de haute qualité en Java peut être étonnamment difficile, et le code qui en résulte peut être assez compliqué. Avec Thumbnailator, il est possible d'exprimer des tâches assez compliquées en utilisant une API simple et fluide.
Un exemple simple
Pour un exemple simple, prendre une image et la redimensionner à 100 x 100 (en préservant le rapport hauteur / largeur de l'image d'origine) et l'enregistrer dans un fichier peut être réalisée en une seule instruction:
Cette bibliothèque utilise également la méthode de mise à l' échelle bilinéaire progressive mise en évidence dans Filthy Rich Clients de Chet Haase et Romain Guy afin de générer des vignettes de haute qualité tout en garantissant des performances d'exécution acceptables.
Vous n'avez pas besoin d'une bibliothèque pour cela. Vous pouvez le faire avec Java lui-même.
Chris Campbell a un excellent article détaillé sur la mise à l'échelle 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 de l'image dans leur livre, Filthy Rich Clients .
L'article de Chris est exactement ce qui m'a motivé à écrire imgscalr en premier lieu; et des questions comme celle-ci (et des réponses comme la vôtre). Beaucoup de gens demandent encore et encore comment obtenir de belles vignettes à partir d'une image. Il y a plusieurs façons de le faire, Chris n'est pas toujours la meilleure façon, cela dépend de ce que vous essayez de faire et de l'ampleur de la réduction. imgscalr répond à tout cela et c'est une classe.
Riyad Kalla
2
+1, je suis d'accord, Filthy Rich clients est l'un des meilleurs livres java à égalité avec "Effective java", mais ImgScalr est ce que j'utilise parce que je suis paresseux.
Shawn Vader
10
Java Advanced Imaging est désormais open source et fournit les opérations dont vous avez besoin.
Si vous avez affaire à de grandes images ou que vous voulez un joli résultat, ce n'est pas une tâche triviale 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 nécessite plus de travail que vous ne l'imaginez pour obtenir quelque chose qui semble bon et JAI a la mauvaise habitude de faire exploser votre JVM avec des erreurs OutOfMemory.
Je suggère d'utiliser ImageMagick comme 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.
Si, avoir imagemagick installé sur votre machine est une option, je recommande im4java . C'est une couche d'abstraction très fine sur l'interface de ligne de commande, mais fait très bien son travail.
Il est également disponible sur GitHub ( github.com/mortennobel/java-image-scaling.git ) et il a la version 8.7 pour l'instant. Il avait besoin d'un correctif li'l dans pom.xml, toi (changer la source et la cible à au moins 1.6 car le plus récent Maven ne supporte plus la 1.5).
Image Magick a été mentionnée. Il existe un projet frontal JNI appelé JMagick. Ce n'est pas un projet particulièrement stable (et Image Magick lui-même est connu pour changer beaucoup et même casser la compatibilité). Cela dit, nous avons une bonne expérience de l'utilisation de JMagick et d'une version compatible d'Image Magick dans un environnement de production pour effectuer une mise à l'échelle à un débit élevé et à un faible taux de latence. La vitesse était nettement meilleure qu'avec une bibliothèque graphique entièrement Java que nous avions précédemment essayée.
Vous pouvez également définir la valeur sur BICUBIC, cela produira une image de meilleure qualité mais c'est une opération plus coûteuse. Il existe d'autres conseils de rendu que vous pouvez définir, mais j'ai trouvé que l'interpolation produit l'effet le plus notable. Gardez à l'esprit que si vous souhaitez zoomer beaucoup, le code java sera très probablement très lent. Je trouve que les images plus grandes commencent à produire un décalage d'environ 300% de zoom, même avec tous les conseils de rendu définis pour optimiser la vitesse par rapport à la qualité.
Il s'avère que l'écriture d'un scaler 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 y a un bogue désagréable avec cela - reportez-vous à mon lien pour plus de détails.
J'ai développé une solution avec les classes disponibles gratuitement (AnimatedGifEncoder, GifDecoder et LWZEncoder) disponibles pour gérer les animations GIF.
Vous pouvez télécharger le fichier jgifcode et exécuter la classe GifImageUtil. Lien: http://www.jgifcode.com
Si vous ne voulez pas importer imgScalr comme la réponse @Riyad Kalla ci-dessus que j'ai testée fonctionne aussi bien, vous pouvez le faire à partir de la réponse de Peter Walser @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.
*/publicIcon getIcon(String name){Icon icon =null;
URL url =null;ImageIcon imgicon =null;BufferedImage scaledImage =null;try{
url = getClass().getResource(name);
icon =newImageIcon(url);if(icon ==null){System.out.println("Couldn't find "+ url);}BufferedImage bi =newBufferedImage(
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 =newImageIcon(scaledImage);}catch(Exception e){System.out.println("Couldn't find "+ getClass().getName()+"/"+ name);
e.printStackTrace();}return imgicon;}publicstaticBufferedImage 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 2int 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 =newBufferedImage(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 =newBufferedImage(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;}}
Réponses:
Après avoir chargé l'image, vous pouvez essayer:
la source
FWIW Je viens de publier (Apache 2, hébergé sur GitHub) une simple bibliothèque de mise à l'échelle d'image pour Java appelée imgscalr (disponible sur Maven central ).
La bibliothèque met en œuvre plusieurs approches différentes de la mise à l'échelle de l'image (y compris l'approche incrémentielle de Chris Campbell avec quelques améliorations mineures) et choisira soit l'approche la plus optimale pour vous si vous le lui demandez, soit vous donnera la plus rapide ou la meilleure apparence (si vous demandez-le).
L'utilisation est extrêmement simple, juste un tas de méthodes statiques. Le cas d'utilisation le plus simple est:
Toutes les opérations conservent les proportions d'origine de l'image, donc dans ce cas, vous demandez à imgscalr de redimensionner votre image dans des limites de 200 pixels de large et 200 pixels de haut et par défaut, il sélectionnera automatiquement la meilleure approche et la plus rapide pour cela depuis 't spécifié.
Je me rends compte dès le départ que cela ressemble à de l'auto-promotion (c'est le cas), mais j'ai passé ma juste part de temps à googler exactement le même sujet et j'ai continué à proposer des résultats / approches / pensées / suggestions différents et j'ai décidé de m'asseoir et d'écrire un implémentation simple qui répondrait à 80 à 85% des cas d'utilisation où vous avez une image et que vous voulez probablement une vignette pour celle-ci - soit aussi vite que possible ou aussi belle que possible (pour ceux qui ont essayé, vous remarquerez faire un Graphics.drawImage même avec une interpolation BICUBIC vers une image suffisamment petite, cela ressemble toujours à une poubelle).
la source
new ImageScaler(img).resizeTo(...).rotate(...).cropTo(...).toOutputBuffer()
. J'aime aussi ton chemin et je pense que c'est plus simple.Thumbnailator est une bibliothèque de redimensionnement d'images 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 vignettes de haute qualité en Java peut être étonnamment difficile, et le code qui en résulte peut être assez compliqué. Avec Thumbnailator, il est possible d'exprimer des tâches assez compliquées en utilisant une API simple et fluide.
Un exemple simple
Pour un exemple simple, prendre une image et la redimensionner à 100 x 100 (en préservant le rapport hauteur / largeur de l'image d'origine) et l'enregistrer dans un fichier peut être réalisée en une seule instruction:
Un exemple avancé
L'exécution de tâches de redimensionnement complexes est simplifiée grâce à l'interface fluide de Thumbnailator.
Supposons que nous voulions faire ce qui suit:
0.85
,thumbnail.
ajoutés au débutTraduit en Thumbnailator, nous pourrions effectuer les opérations ci-dessus avec les éléments suivants:
Une note sur la qualité et la vitesse d'image
Cette bibliothèque utilise également la méthode de mise à l' échelle bilinéaire progressive mise en évidence dans Filthy Rich Clients de Chet Haase et Romain Guy afin de générer des vignettes de haute qualité tout en garantissant des performances d'exécution acceptables.
la source
Vous n'avez pas besoin d'une bibliothèque pour cela. Vous pouvez le faire avec Java lui-même.
Chris Campbell a un excellent article détaillé sur la mise à l'échelle 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 de l'image dans leur livre, Filthy Rich Clients .
la source
Java Advanced Imaging est désormais open source et fournit les opérations dont vous avez besoin.
la source
Si vous avez affaire à de grandes images ou que vous voulez un joli résultat, ce n'est pas une tâche triviale 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 nécessite plus de travail que vous ne l'imaginez pour obtenir quelque chose qui semble bon et JAI a la mauvaise habitude de faire exploser votre JVM avec des erreurs OutOfMemory.
Je suggère d'utiliser ImageMagick comme 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.
la source
Si, avoir imagemagick installé sur votre machine est une option, je recommande im4java . C'est une couche d'abstraction très fine sur l'interface de ligne de commande, mais fait très bien son travail.
la source
L'API Java ne fournit pas de fonction de mise à l'échelle standard pour les images et de rétrogradation de la qualité d'image.
Pour cette raison, j'ai essayé d'utiliser cvResize de JavaCV mais cela semble poser des problèmes.
J'ai trouvé une bonne bibliothèque pour la mise à l'échelle d'image: ajoutez simplement la dépendance pour "java-image-scaling" dans votre pom.xml.
Dans le référentiel maven, vous obtiendrez la version récente pour cela.
Ex. Dans votre programme java
la source
Vous pouvez essayer d'utiliser le système de traitement d'images GraphicsMagick avec im4java comme interface de ligne de commande pour Java.
GraphicsMagick présente de nombreux avantages, mais un pour tous:
la source
Image Magick a été mentionnée. Il existe un projet frontal JNI appelé JMagick. Ce n'est pas un projet particulièrement stable (et Image Magick lui-même est connu pour changer beaucoup et même casser la compatibilité). Cela dit, nous avons une bonne expérience de l'utilisation de JMagick et d'une version compatible d'Image Magick dans un environnement de production pour effectuer une mise à l'échelle à un débit élevé et à un faible taux de latence. La vitesse était nettement meilleure qu'avec une bibliothèque graphique entièrement Java que nous avions précédemment essayée.
http://www.jmagick.org/index.html
la source
Utilisez simplement la réponse de Burkhard mais ajoutez cette ligne après avoir créé les graphiques:
Vous pouvez également définir la valeur sur BICUBIC, cela produira une image de meilleure qualité mais c'est une opération plus coûteuse. Il existe d'autres conseils de rendu que vous pouvez définir, mais j'ai trouvé que l'interpolation produit l'effet le plus notable. Gardez à l'esprit que si vous souhaitez zoomer beaucoup, le code java sera très probablement très lent. Je trouve que les images plus grandes commencent à produire un décalage d'environ 300% de zoom, même avec tous les conseils de rendu définis pour optimiser la vitesse par rapport à la qualité.
la source
Vous pouvez utiliser Marvin (pure infrastructure de traitement d'image Java) pour ce type d'opération: http://marvinproject.sourceforge.net
Plug-in Scale: http://marvinproject.sourceforge.net/en/plugins/scale.html
la source
Il s'avère que l'écriture d'un scaler 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 y a un bogue désagréable avec cela - reportez-vous à mon lien pour plus de détails.
la source
J'ai développé une solution avec les classes disponibles gratuitement (AnimatedGifEncoder, GifDecoder et LWZEncoder) disponibles pour gérer les animations GIF.
Vous pouvez télécharger le fichier jgifcode et exécuter la classe GifImageUtil. Lien: http://www.jgifcode.com
la source
vous pouvez utiliser le produit populaire suivant: miniature
la source
Si vous ne voulez pas importer imgScalr comme la réponse @Riyad Kalla ci-dessus que j'ai testée fonctionne aussi bien, vous pouvez le faire à partir de la réponse de Peter Walser @Peter Walser sur un autre problème:
la source
Essayez cette méthode suivante:
la source