Précédent   Forum du club des développeurs et IT Pro > Java > Communauté Java > Contribuez
Contribuez Proposez vos articles, cours, tutoriels, FAQ, sources, et autres ressources pour la rubrique Java.
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 18/11/2008, 14h55   #1
millie
Rédacteur/Modérateur
 
Avatar de millie
 
Inscription : juin 2006
Messages : 6 935
Détails du profil
Informations personnelles :
Localisation : Luxembourg

Informations forums :
Inscription : juin 2006
Messages : 6 935
Points : 9 062
Points : 9 062
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é
millie est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/11/2008, 14h33   #2
eclesia
Rédacteur
 
Avatar de eclesia
 
Inscription : décembre 2006
Messages : 1 876
Détails du profil
Informations forums :
Inscription : décembre 2006
Messages : 1 876
Points : 2 254
Points : 2 254
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 : GeoAPI GeotoolKit PuzzleGIS

Pour un monde sans BigBrother IxQuick ni censure RSF
eclesia est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/11/2008, 14h39   #3
millie
Rédacteur/Modérateur
 
Avatar de millie
 
Inscription : juin 2006
Messages : 6 935
Détails du profil
Informations personnelles :
Localisation : Luxembourg

Informations forums :
Inscription : juin 2006
Messages : 6 935
Points : 9 062
Points : 9 062
Mais ça fait des thumbnails tout pourri...

Méthode classique avec interpolation simple


Méthode avec le smooth
Images attachées
Type de fichier : jpg thumb1.jpg (16,7 Ko, 178 affichages)
Type de fichier : jpg thumb2.jpg (10,3 Ko, 176 affichages)
__________________
Je ne répondrai à aucune question technique en privé
millie est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/11/2008, 22h28   #4
eclesia
Rédacteur
 
Avatar de eclesia
 
Inscription : décembre 2006
Messages : 1 876
Détails du profil
Informations forums :
Inscription : décembre 2006
Messages : 1 876
Points : 2 254
Points : 2 254
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 : GeoAPI GeotoolKit PuzzleGIS

Pour un monde sans BigBrother IxQuick ni censure RSF
eclesia est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/11/2008, 22h34   #5
millie
Rédacteur/Modérateur
 
Avatar de millie
 
Inscription : juin 2006
Messages : 6 935
Détails du profil
Informations personnelles :
Localisation : Luxembourg

Informations forums :
Inscription : juin 2006
Messages : 6 935
Points : 9 062
Points : 9 062
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é
millie est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/01/2009, 19h18   #6
sinok
Modérateur
 
Avatar de sinok
 
Inscription : août 2004
Messages : 8 633
Détails du profil
Informations personnelles :
Âge : 33
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : août 2004
Messages : 8 633
Points : 12 433
Points : 12 433
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.
sinok est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/01/2009, 19h22   #7
millie
Rédacteur/Modérateur
 
Avatar de millie
 
Inscription : juin 2006
Messages : 6 935
Détails du profil
Informations personnelles :
Localisation : Luxembourg

Informations forums :
Inscription : juin 2006
Messages : 6 935
Points : 9 062
Points : 9 062
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é
millie est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/01/2009, 19h25   #8
millie
Rédacteur/Modérateur
 
Avatar de millie
 
Inscription : juin 2006
Messages : 6 935
Détails du profil
Informations personnelles :
Localisation : Luxembourg

Informations forums :
Inscription : juin 2006
Messages : 6 935
Points : 9 062
Points : 9 062
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é
millie est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/01/2010, 23h17   #9
millie
Rédacteur/Modérateur
 
Avatar de millie
 
Inscription : juin 2006
Messages : 6 935
Détails du profil
Informations personnelles :
Localisation : Luxembourg

Informations forums :
Inscription : juin 2006
Messages : 6 935
Points : 9 062
Points : 9 062
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é
millie est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/01/2010, 23h45   #10
sinok
Modérateur
 
Avatar de sinok
 
Inscription : août 2004
Messages : 8 633
Détails du profil
Informations personnelles :
Âge : 33
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : août 2004
Messages : 8 633
Points : 12 433
Points : 12 433
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.
sinok est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/01/2010, 08h54   #11
millie
Rédacteur/Modérateur
 
Avatar de millie
 
Inscription : juin 2006
Messages : 6 935
Détails du profil
Informations personnelles :
Localisation : Luxembourg

Informations forums :
Inscription : juin 2006
Messages : 6 935
Points : 9 062
Points : 9 062
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é
millie est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 13h03.


 
 
 
 
Partenaires

Hébergement Web