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

2D Java Discussion :

Rotation d'une image dans un JButton


Sujet :

2D Java

  1. #1
    Membre régulier
    Inscrit en
    Septembre 2002
    Messages
    200
    Détails du profil
    Informations forums :
    Inscription : Septembre 2002
    Messages : 200
    Points : 120
    Points
    120
    Par défaut Rotation d'une image dans un JButton
    Bonjour, je souhaite simplement tourner une image contenue dans un JButton mais je ne sais pas comment faire. J'ai mon widget (le JButton) auquel j'ajoute une image de fond :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    widget.setIcon( imgReleased);
    Cette "imgReleased", je l'obtiens comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    imageReleased = new ImageIcon( 	imageTmp.getImage().getScaledInstance( 	(int)(imageTmp.getIconWidth()*getWindowRatio()), 
    													(int)(imageTmp.getIconHeight()*getWindowRatio()), 
    													Image.SCALE_DEFAULT));
    C'est donc une ImageIcon.

    Mon désir est donc de tourner cette image et la remettre tournée sur le bouton. Voici ce à quoi j'avais pensé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    AffineTransform lAf = new AffineTransform();
    lAf.rotate(pRotationAngle);
     
    Graphics lG = imageReleased.getImage().getGraphics();
    if ( lG != null ){
    	((Graphics2D) lG).setTransform(lAf);
    	widget.setIcon(imageReleased);
    }
    Mais bon deja ca plante par une "UnsupportedOperationException" : getGraphics not supported for image created with CreateImage... !!!

    Etrange, comment puis-je faire ?
    Merci pour votre aide !
    Alexandre.

  2. #2
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 807
    Points
    48 807
    Par défaut
    Tu crée un bufferedImage, tu lui applique une transformation (rotation, scaling), tu y "copie" l'image d'origine, tu crée un imageicon à partir du bufferedimage et voilà

  3. #3
    Membre régulier
    Inscrit en
    Septembre 2002
    Messages
    200
    Détails du profil
    Informations forums :
    Inscription : Septembre 2002
    Messages : 200
    Points : 120
    Points
    120
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Tu crée un bufferedImage, tu lui applique une transformation (rotation, scaling), tu y "copie" l'image d'origine, tu crée un imageicon à partir du bufferedimage et voilà

    Merci pour ton aide ca a l'air sympa.
    Je cherche juste ce que tu entends par tu y copies l'image d'origine...
    Comment créer un BufferedImage (sans info), et comment lui ajouter le ImageIcon d'origine ?

    Merci, a plus

  4. #4
    Membre régulier
    Inscrit en
    Septembre 2002
    Messages
    200
    Détails du profil
    Informations forums :
    Inscription : Septembre 2002
    Messages : 200
    Points : 120
    Points
    120
    Par défaut
    En fait finalement j'ai fait comme ca et ca ne change rien à mon image.... (pas de rotation !). Mais bon j'y connais pas grand chose c'est bien le problème:

    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
     
    public void rotate(short pRotationAngle){
        	AffineTransform lAf = new AffineTransform();
        	lAf.rotate(pRotationAngle);
     
        	try{
        		BufferedImage 	lBi	= ImageIO.read(imageReleasedFile);
        		Graphics2D 		lG2	= lBi.createGraphics() ;
        		lG2.setTransform(lAf);
        		imageReleased = new ImageIcon( lBi );
        		widget.setIcon(imageReleased);
        	}
        	catch (IOException e){
        		e.printStackTrace();
        	}    	    	      
        }
    Bien sur imageReleasedFile est un objet de ma classe de type File.

    Egalement: savez-vous en quel unité doit etre passé le pRotationAngle ? Si je passe 25 pour essayé c'est significatif ?

    Merci pour votre aide.
    Alexandre.

  5. #5
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 851
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 851
    Points : 22 863
    Points
    22 863
    Billets dans le blog
    51
    Par défaut
    Fouillalala quel melange de concepts...

    setTransform() change la transformation du Graphics et impacte tout ce qui est dessinne APRES dedans. Ce n'est en aucun cas quelques chose qu'on positionne pour modifier dynamiquement l'apparence du rendu de l'image apres coup au moment de l'affichage.

    Evidement il faut que la nouvelle image transformée soit une image différente de la premiere. Visiblement la tu ne dessines pas ton ancienne image dans le Graphics de la nouvelle avec drawImage().

    Autres problemes :

    - Les dimensions de l'image destination. Prend une feuille de papier découpée en carre (ton image source), tourne-la de 45° (par rapport au centre du carre, voir point suivant)... le losange résultant a une boite carre engloblante qui prend plus de place que l'image d'origine... Donc si ton image destination a les dimensions de l'image source, ben des bouts vont etre coupés.

    - le centre de rotation. M'est avis que tu n'as pas vraiment envie d'une rotation autour de (0, 0) mais autour du centre de l'image source. Pareil, fait des tests avec ta feuille de papier et tu verras qu'assez vite l'image rotationnee sort de la zone d'affichage et que rien ne s'affiche plus si tu tournes autour de (0, 0) au lieu de tourner autour du centre de l'image.

    Va falloir ressortir les bouquins de trigo.

    Cree une nouvelle BufferedImage est aussi rapide et facile qu'appeler le constructeur de cette classe décrit dans la javadoc ou dans la ...

    Apres il existe d'autres methodes avances qui permettent de creer une BufferedImage compatible histoire d'avoir un affichage plus rapide et donc nous reparleront apres.

    Note : en fait il n'est pas du tout necessaire de creer une nouvelle image "physique" pour avoir une image transformee (même si c'est une bonne méthode pour comprendre comme faire de la 2D). Il suffit en fait de creer une nouvelle classe héritant de l'interface Icon et d'implementant correctement les méthodes retournant les dimensions de l'icone (voir livre de trigo) et celle du rendu pour avoir un dessin de l'image rotationnée "au vol"...

  6. #6
    Membre régulier
    Inscrit en
    Septembre 2002
    Messages
    200
    Détails du profil
    Informations forums :
    Inscription : Septembre 2002
    Messages : 200
    Points : 120
    Points
    120
    Par défaut
    Ok, d'accord d'accord.... Alors conceptuellement j'y connais rien du tout. J'ai jamais fait de Swing ou AWT, et ce besoin est ponctuel pour mon boulot. Le postulat est simple: j'ai une image qui représente un bouton rond, c'est donc un PNG détouré avec de la transparence autour. Pas besoin de m'occuper, donc, de la taille de l'image finale.

    Je voudrais savoir comment, le plus simplement du monde, le plus salement du monde, et sans chercher des concepts ultra complexe, tourner mon image.

    Le poste de tchize paraissait tellement simple à implémenté qu'il m'avait redonné espoir.... Mais apparemment j'avais pas tout compris. Dans cette optique, y a t il des morceaux de code sur lesquels je puisse m'inspirer ???

    Je ne demande pas comment réaliser un moteur de rendu 3D avec radiosité ou des algos d'IA pour des scènes cinématographiques !!! Juste de tourner une image, sans rien m'occuper d'autre....

    BufferedImage n'est pas le bon plan alors pour ca, contrairement a ce que disait tchize ??

    Merci, a plus.

    PS:
    Cree une nouvelle BufferedImage est aussi rapide et facile qu'appeler le constructeur de cette classe décrit dans la javadoc
    J'ai jamais dit que c'était dur de lire une doc ou d'appeler un construteur, je ne vois pas le hic.. d'ailleurs je l'ai fait dans mon précédent message...

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

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Points : 12 977
    Points
    12 977
    Par défaut
    Quand tu dis tourner, tu as combien d'états possibles pour ton image, Si tu en as seulement 2, tu fais deux images physiques avec n'importe quel logiciel de dessin et tu les change alternativement avec la méthode setIcon de ton JButton quand le besoin s'en fait sentir...

  8. #8
    Membre régulier
    Inscrit en
    Septembre 2002
    Messages
    200
    Détails du profil
    Informations forums :
    Inscription : Septembre 2002
    Messages : 200
    Points : 120
    Points
    120
    Par défaut
    Oui j'avais songé à cette éventualité, mais non en fait je veux faire un rotactor, une sorte de bouton avionique comme le serait les anciens boutons de réglage des autoradio. Cet objet doit avoir 365 positions, par incrément de 1. J'ai pas vraiment envie de faire autant d'images.... Mais merci pour l'astuce.

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

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Points : 12 977
    Points
    12 977

  10. #10
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 807
    Points
    48 807
    Par défaut
    Salement:

    Tu crée un bufferedimage (vide, au bon format (ARGB) et bonne taille)!
    Tu prend son graphics
    Tu applique des affine transform (translation +rotation + translationinverse)
    Tu fais un graphics.drawImage(imageD'origine), çà va dessiner tourné l'image d'orignie dans bufferedImage
    Tu crée finalement un objet ImageIcon à partir de ton bufferedImage

    Ca, c'est la méthode sale. Dans ton cas, comme suggéré, tu peux créer une classe qui implémente l'interface icon et fait l'opération de rotation au vol...

  11. #11
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 851
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 851
    Points : 22 863
    Points
    22 863
    Billets dans le blog
    51
    Par défaut
    Tu as plein plein de solutions :
    - creer tout un tas de fichiers images montrant les differents etats de rotation du bouton et tous les charger en mémoire.

    - creer une seule image dans un fichier, la charger puis créer toutes les images mémoires correspondant aux différents états.

    - faire comme j'ai indiqué.

    Apres a toi de voir ce qui offre le meilleur rapport vitesse de rendu/qualité de rendu/occupation en memoire.

    Moi je serai plus partant de la surcharge d'Icon, éventuellement avec un cache permettant de stocker les images des rotations les plus souvent utilisées.

  12. #12
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 807
    Points
    48 807
    Par défaut
    Si il a 255 états de rotation, stocker l'icone en 25 exemplaire, çà va vite bouffer la mémoire

  13. #13
    Membre régulier
    Inscrit en
    Septembre 2002
    Messages
    200
    Détails du profil
    Informations forums :
    Inscription : Septembre 2002
    Messages : 200
    Points : 120
    Points
    120
    Par défaut
    Bonjour, merci beaucoup pour vos réponses qui m'ont vraiment aidé, et surtout tchize.
    J'ai évidemment opté pour la solution crade car je n'ai pas de temps a y consacrer, d'ailleurs j'avais zappé un moment ce projet et je m'y remets.

    Je tiens également a signaler que j'ai essayé le JXTransformer, ca marche bien (j'ai passé 4h dessus !!) mais ca n'est pas compatible avec ce que je voulais faire car il fallait encapsuler tous mes éléments graphiques dans des Panels.

    Bref, pour la solution crade voici mon code qui pourrait aider d'autres personnes:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
        	AffineTransform lAt = new AffineTransform();
        	lAt.translate(imageReleased.getIconWidth()/2, imageReleased.getIconHeight()/2);
        	lAt.rotate(Math.toRadians(pRotationAngle));
        	lAt.translate(-imageReleased.getIconWidth()/2, -imageReleased.getIconHeight()/2);
     
    	BufferedImage 	lBi	= new BufferedImage( imageReleased.getIconWidth(), imageReleased.getIconHeight(), BufferedImage.TYPE_INT_ARGB );
    	Graphics2D 		lG2	= lBi.createGraphics() ;    		
    	lG2.drawImage(imageReleased.getImage(), lAt, null);
    	ImageIcon lNewImage = new ImageIcon( lBi );
    	widget.setIcon(lNewImage);
    Avec
    pRotationAngle = un short qui défini l'angle (-180...180)
    imageReleased = type ImageIcon
    Encore merci, ciao.

    Cordialement,
    Alexandre.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Rotation d'une image dans un UserForm
    Par VicomteRaoul dans le forum VBA Word
    Réponses: 5
    Dernier message: 26/12/2022, 12h28
  2. WX.python Rotation d'une image dans un panneau
    Par shanoc dans le forum wxPython
    Réponses: 5
    Dernier message: 07/04/2014, 17h40
  3. [problème] affichage d'une image dans un JButton
    Par shadowpath dans le forum Composants
    Réponses: 3
    Dernier message: 16/06/2008, 09h20
  4. Redimensionner une image dans un JButton
    Par mooch dans le forum Interfaces Graphiques en Java
    Réponses: 2
    Dernier message: 06/03/2008, 23h47
  5. Comment améliorer la rotation à 45° d'une image dans un PictureBox
    Par ProgElecT dans le forum VB 6 et antérieur
    Réponses: 6
    Dernier message: 22/07/2006, 01h05

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