Publicité
+ Répondre à la discussion
Affichage des résultats 1 à 11 sur 11
  1. #1
    Rédacteur/Modérateur

    Avatar de millie
    Profil pro
    Inscrit en
    juin 2006
    Messages
    6 945
    Détails du profil
    Informations personnelles :
    Localisation : Luxembourg

    Informations forums :
    Inscription : juin 2006
    Messages : 6 945
    Points : 8 774
    Points
    8 774

    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 :
    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
    Inscrit en
    décembre 2006
    Messages
    1 973
    Détails du profil
    Informations forums :
    Inscription : décembre 2006
    Messages : 1 973
    Points : 2 484
    Points
    2 484

    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)

  3. #3
    Rédacteur/Modérateur

    Avatar de millie
    Profil pro
    Inscrit en
    juin 2006
    Messages
    6 945
    Détails du profil
    Informations personnelles :
    Localisation : Luxembourg

    Informations forums :
    Inscription : juin 2006
    Messages : 6 945
    Points : 8 774
    Points
    8 774

    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
    Inscrit en
    décembre 2006
    Messages
    1 973
    Détails du profil
    Informations forums :
    Inscription : décembre 2006
    Messages : 1 973
    Points : 2 484
    Points
    2 484

    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

  5. #5
    Rédacteur/Modérateur

    Avatar de millie
    Profil pro
    Inscrit en
    juin 2006
    Messages
    6 945
    Détails du profil
    Informations personnelles :
    Localisation : Luxembourg

    Informations forums :
    Inscription : juin 2006
    Messages : 6 945
    Points : 8 774
    Points
    8 774

    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
    Modérateur
    Avatar de sinok
    Profil pro
    Inscrit en
    août 2004
    Messages
    8 756
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : août 2004
    Messages : 8 756
    Points : 11 827
    Points
    11 827

    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 :
    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 :
    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 :
    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/Modérateur

    Avatar de millie
    Profil pro
    Inscrit en
    juin 2006
    Messages
    6 945
    Détails du profil
    Informations personnelles :
    Localisation : Luxembourg

    Informations forums :
    Inscription : juin 2006
    Messages : 6 945
    Points : 8 774
    Points
    8 774

    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/Modérateur

    Avatar de millie
    Profil pro
    Inscrit en
    juin 2006
    Messages
    6 945
    Détails du profil
    Informations personnelles :
    Localisation : Luxembourg

    Informations forums :
    Inscription : juin 2006
    Messages : 6 945
    Points : 8 774
    Points
    8 774

    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/Modérateur

    Avatar de millie
    Profil pro
    Inscrit en
    juin 2006
    Messages
    6 945
    Détails du profil
    Informations personnelles :
    Localisation : Luxembourg

    Informations forums :
    Inscription : juin 2006
    Messages : 6 945
    Points : 8 774
    Points
    8 774

    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
    Modérateur
    Avatar de sinok
    Profil pro
    Inscrit en
    août 2004
    Messages
    8 756
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : août 2004
    Messages : 8 756
    Points : 11 827
    Points
    11 827

    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/Modérateur

    Avatar de millie
    Profil pro
    Inscrit en
    juin 2006
    Messages
    6 945
    Détails du profil
    Informations personnelles :
    Localisation : Luxembourg

    Informations forums :
    Inscription : juin 2006
    Messages : 6 945
    Points : 8 774
    Points
    8 774

    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é

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •