IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Contribuez Java Discussion :

[Source] Création de thumbnails à partir de BufferedImage


Sujet :

Contribuez Java

  1. #1
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Points : 9 818
    Points
    9 818
    Par défaut [Source] Création de thumbnails à partir de BufferedImage
    Bonjour,

    Voici 2 méthodes pour créer des Thumbnails à partir d'un BufferedImage.

    On utilise un SCALE_SMOOTH pour avoir une image réduite "potable" niveau visualisation.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    public static BufferedImage reduceImage(BufferedImage input, int newwidth,
    			int newheight) {
    		BufferedImage out = null;
    		//on choisie le type de couleur suivant le nombre de composants
    		if(input.getColorModel().getNumColorComponents() == 1)
    		 out = new BufferedImage(newwidth, newheight, BufferedImage.TYPE_BYTE_GRAY);
    		else
    			out = new BufferedImage(newwidth, newheight, BufferedImage.TYPE_INT_RGB);
     
    		Graphics2D g = out.createGraphics();
    		System.err.println("Temp color model : " + input.getColorModel());
    		Image scaled = input.getScaledInstance(newwidth, newheight,	Image.SCALE_SMOOTH); //on utilise un SCALE_SMOOTH pour obtenir une petite image correcte
    		g.drawImage(scaled, 0, 0, out.getWidth(), out.getHeight(), null);
    		g.dispose();
    		return out;
    	}
     
    	public static BufferedImage reduceImage(BufferedImage input, float factor) {
    		int newwidth = (int) (((double) input.getWidth()) * factor);
    		int newheight = (int) (((double) input.getHeight()) * factor);
    		return reduceImage(input, newwidth, newheight);
    	}
    Je ne répondrai à aucune question technique en privé

  2. #2
    Rédacteur
    Avatar de eclesia
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    2 108
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 108
    Points : 3 203
    Points
    3 203
    Par défaut
    pour la methode avec parametre factor, tu pourrais passer plus simplement par une modification du affinetransform de l'object graphic2D. (c'est aussi meilleur niveau perf)
    Systèmes d'Informations Géographiques
    - Projets : Unlicense.science - Apache.SIS

    Pour un monde sans BigBrother IxQuick ni censure RSF et Les moutons

  3. #3
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Points : 9 818
    Points
    9 818
    Par défaut
    Mais ça fait des thumbnails tout pourri...

    Méthode classique avec interpolation simple


    Méthode avec le smooth
    Images attachées Images attachées   
    Je ne répondrai à aucune question technique en privé

  4. #4
    Rédacteur
    Avatar de eclesia
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    2 108
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 108
    Points : 3 203
    Points
    3 203
    Par défaut
    il faut penser aux hints java2d .

    http://java.sun.com/docs/books/tutor...d/quality.html

    celui la en particulier pour tes images : KEY_INTERPOLATION
    Systèmes d'Informations Géographiques
    - Projets : Unlicense.science - Apache.SIS

    Pour un monde sans BigBrother IxQuick ni censure RSF et Les moutons

  5. #5
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Points : 9 818
    Points
    9 818
    Par défaut
    Citation Envoyé par eclesia Voir le message
    il faut penser aux hints java2d .

    http://java.sun.com/docs/books/tutor...d/quality.html

    celui la en particulier pour tes images : KEY_INTERPOLATION
    T'inquiètes, j'ai tout essayé avec des interpolations linéaires/bilinéaires, ça ne donnait pas des résultats aussi bon au moins sur des images de type texte

    L'image mauvaise que tu vois, je crois que c'était une interpolation linéaire (et bilinéaire, c'était pas beaucoup mieux)

    Mais ça peut effectivement dépendre de l'image source. Pour une photo, c'est OK, pour une image avec plein de détails comme du texte, c'est pas bon


    EDIT : Ah, tu parlais du KEY_TEXT ?
    Je ne répondrai à aucune question technique en privé

  6. #6
    Expert éminent sénior
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Points : 12 977
    Points
    12 977
    Par défaut
    Euh, mieux vaut en général ne pas utiliser le getScaledInstance (oui je sais bis répétita), trop lent dans une appli pour le calcul de thumbnails.

    http://today.java.net/pub/a/today/20...dinstance.html

    La manière de procéder à recommander serait plutôt la suivante:

    Citation Envoyé par Gfx (aka Romain Guy)
    Il ne faut JAMAIS utiliser getScaledInstance(). JAMAIS. Cette methode est 20 a 30 fois plus lente que l'autre solution :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    Image imageAReduire = ...;
    // ...
    BufferedImage image = new BufferedImage(BufferedImage.TYPE_INT_ARGB, imageAReduire.getWidth(null), imageAReduire.getHeight(null));
    Graphics2D g2 = image.createGraphics();
    g2.drawImage(imageAReduire, 0, 0, nouvelleLargeur, nouvelleHauteur, null);
    g2.dispose();
    La methode Graphics.drawImage() permet de redimensionner l'image grace a la carte graphique. Pour avoir un plus joli resultat tu peux rajouter cela avant le drawImage() :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
    Le resultat ne sera agreable que si ta version reduite de l'image a des dimensions proches de celles d'origine divisees par deux. Si tu reduis plus il faut utiliser une approche proche de la technique du mip mapping :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
            public static BufferedImage createThumbnail(BufferedImage image, int requestedThumbSize) {
            float ratio = (float) image.getWidth() / (float) image.getHeight();
            int width = image.getWidth();
            BufferedImage thumb = image;
     
            do {
                width /= 2;
                if (width < requestedThumbSize) {
                    width = requestedThumbSize;
                }
     
                BufferedImage temp = new BufferedImage(width, (int) (width / ratio), BufferedImage.TYPE_INT_ARGB);
                Graphics2D g2 = temp.createGraphics();
                g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                                    RenderingHints.VALUE_INTERPOLATION_BILINEAR);
                g2.drawImage(thumb, 0, 0, temp.getWidth(), temp.getHeight(), null);
                g2.dispose();
     
                thumb = temp;
            } while (width != requestedThumbSize);
     
            return thumb;
        }
    Et non, cette solution n'est pas vraiment plus lente que celle en une seule etape
    Hey, this is mine. That's mine. All this is mine. I'm claiming all this as mine. Except that bit. I don't want that bit. But all the rest of this is mine. Hey, this has been a really good day. I've eaten five times, I've slept six times, and I've made a lot of things mine. Tomorrow, I'm gonna see if I can't have sex with something.

  7. #7
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Points : 9 818
    Points
    9 818
    Par défaut
    Je testerais demain. Mais je doute de la qualité du résultat avec une image texte. Une interpolation bilinéaire n'améliore pas vraiment les images textes.
    Je ne répondrai à aucune question technique en privé

  8. #8
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Points : 9 818
    Points
    9 818
    Par défaut
    En fait, je suis bête. Je confirme, mon image de teste est en interpolation bilinéaire :



    C'est une méthode non adaptée au texte.
    Je ne répondrai à aucune question technique en privé

  9. #9
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Points : 9 818
    Points
    9 818
    Par défaut
    Citation Envoyé par millie Voir le message
    C'est une méthode non adaptée au texte.
    Je remonte pour préciser, mais c'est en fait non adapté à tout ce qui contient des détails fins.
    Je ne répondrai à aucune question technique en privé

  10. #10
    Expert éminent sénior
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Points : 12 977
    Points
    12 977
    Par défaut
    Citation Envoyé par millie Voir le message
    Je remonte pour préciser, mais c'est en fait non adapté à tout ce qui contient des détails fins.
    Bon en même temps des thumbnails, c'est pas sensé être hyper précis en fait....

    Le drawImage direct marche correctement jusqu'à une division de taille par deux, au delà...
    Hey, this is mine. That's mine. All this is mine. I'm claiming all this as mine. Except that bit. I don't want that bit. But all the rest of this is mine. Hey, this has been a really good day. I've eaten five times, I've slept six times, and I've made a lot of things mine. Tomorrow, I'm gonna see if I can't have sex with something.

  11. #11
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Points : 9 818
    Points
    9 818
    Par défaut
    Citation Envoyé par sinok Voir le message
    Le drawImage direct marche correctement jusqu'à une division de taille par deux, au delà...
    Maintenant, avec les photos "standards" des appareils qui font plus de 3000*2000. On se retrouve vite à devoir diviser la taille par 3 pour pouvoir les voir sur nos écrans
    La plupart du temps, cela ne gène pas, mais dans certains cas, ça fait assez pixellisé. Je l'avais particulièrement remarqué quand j'ai voulu faire un système de diaporama (comme les images sont préchargés en avance, de refaire un scaledImage ne posait pas forcement de problème de perf.)
    Je ne répondrai à aucune question technique en privé

Discussions similaires

  1. Réponses: 0
    Dernier message: 09/07/2014, 13h00
  2. Réponses: 4
    Dernier message: 05/10/2005, 16h07
  3. Modifier la source d'un Iframe à partir d'une autre fenêtre
    Par Dan_Rich dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 04/10/2005, 08h11
  4. Réponses: 22
    Dernier message: 03/08/2005, 00h28

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo