Bonjour,
Je réalise une application dans laquelle j'ai un canvas où, par un clique, on une image est dessiner sur le canvas là où l'on a cliqué.

Cette image peut être agrandie ou rétrécie et pivotée.

Pour cela, je dispose d'un petit cavas à coté pour visualiser l'image à insérer et de trois bouton pour la modifier.
Dans ce canvas là, pas de problème.

Mon problème vient de l'*insertion* dans le grand canvas.
j'écris *insertion* car je passe en réalité des paramètres issus du petit canvas et qui me servent à dessiner l'image dans le grand.

Le problème vient du fais de la rotation :
la rotation se fait ( je translate l'image pour la recentré après, donc pas de problème de bord) mais lors de l'affichage, l'image est comme... déformée.

Comme si plusieurs rotations se faisaient et s'imprimaient dans l'image, c'est assez bizzard... (mais assez marrant selon l'image que vous utilisez...)


J'ai essayé plusieurs manière de faire tourner mon image, mais le problème est (presque) le même avec chaque méthode.

Je vous met mes class :

la class FCourbe est ma fenetre principal
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
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
 
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.swing.*;
 
@SuppressWarnings("serial")
public class FCourbe extends JFrame{
 
     Container javaPaint;	//Fenêtre principale
     UTIL_PAINT_Dessin unDessin;		//Cadre de Dessin
 
	 //////////////////// Panneau d'outils et de couleurs ////////////////////
	 JPanel panneau			=new JPanel();	//Ensemble
 
 
     //////// Icônes ////////////////////
	 ImageIcon imageCrayon	=new ImageIcon("crayon.gif");
	 ImageIcon imagePinceau	=new ImageIcon("pinceau.gif");
	 ImageIcon imageEfface	=new ImageIcon("efface.gif");
 
 
 
 
 
	 //////////////////// Boutons ////////////////////
	 //Outils
	 JButton crayon		=new JButton(imageCrayon);
	 private UTIL_VisuImage VisuDess;
	 private JTextField jTxt_titreDessin;
	 private JLabel jLabel_Titre;
	 private JButton jBtn_ZoomPlus;
	 private JButton jBtn_ZoomMoins;
	 private JButton jBtn_Tourner;
	 private Canvas Pellicule;
	 private JButton jBtn_UnAutre;
	 private JButton jBtn_Suite;
	 private JButton jBtn_Retour;
	 public int Xplus=0;
	 public int Yplus=0;
	 public int Angle=0;
	 JButton efface		=new JButton(imageEfface);
	 JButton jBtn_selectImage = new JButton();
	 private JTextPane jTextConsignes;
 
//Le constructeur:
 
     public FCourbe() throws IOException{
        super			("Entrainement Ligne");	//Titre
        unDessin		=new UTIL_PAINT_Dessin();//Le dessin
 
        unDessin.setForeground(Color.white);
        unDessin.setBackground(Color.white);
        //////////////////// Conteneur Principal ////////////////////
        javaPaint		=getContentPane();
        javaPaint.setLayout(null);
 
        	//Outils
        	crayon	.addActionListener(new crayon());
        	efface	.addActionListener(new efface());
        	jBtn_selectImage.addActionListener(new insertimage());
        //////////////////// AJOUT ////////////////////
        //Panneau
        panneau.setLayout(null);
 
        //Java Paint
        javaPaint.add(unDessin);
        unDessin.setBounds(380, 10, 272, 288);
        unDessin.setForeground(new java.awt.Color(192,192,192));
        unDessin.setFocusable(false);
        javaPaint.add(panneau);
        panneau.setBounds(669, 24, 101, 156);
        panneau.setBackground(new java.awt.Color(250,232,197));
        panneau.setVisible(true);
        {
        	jTextConsignes = new JTextPane();
        	javaPaint.add(jTextConsignes);
        	jTextConsignes.setText(new UTIL_LireFichierTXT().getText(Consignes));
        	jTextConsignes.setBounds(12, 11, 231, 169);
        	jTextConsignes.setEditable(false);
        }
        {
        	jBtn_Retour = new JButton(new ImageIcon("ressources/Comprendre/Icon/IconRetour.gif"));
        	javaPaint.add(jBtn_Retour);
        	jBtn_Retour.setText("Retour");
        	jBtn_Retour.addActionListener(
				      new ActionListener(){
						@SuppressWarnings("deprecation")
						public void actionPerformed(ActionEvent e){
 
				             Event inst1 = null;
				             jBtn_Suite.getParent().getParent().getParent().action(inst1,WindowConstants.DISPOSE_ON_CLOSE);
				      }/*end actionPerformed*/}/*end ActionListener*/);//end addActionListener()
        	jBtn_Retour.setBounds(647, 499, 90, 25);
        }
        {
        	jBtn_Suite = new JButton(new ImageIcon("ressources/Comprendre/Icon/IconSuite.gif"));
        	javaPaint.add(jBtn_Suite);
        	jBtn_Suite.setText("Suite");
        	jBtn_Suite.addActionListener(new ActionListener(){@SuppressWarnings("deprecation")
						public void actionPerformed(ActionEvent e){
 
							//Enregistrer l'image
							//passer a la nouvelle etape(fenetre) et fermer celle-ci
 
				             jBtn_Suite.getParent().getParent().getParent().getParent().setVisible(false);
				             Event inst = null;
				             jBtn_Suite.getParent().getParent().getParent().action(inst,WindowConstants.DISPOSE_ON_CLOSE);
 
				      }/*end actionPerformed*/}/*end ActionListener*/);//end addActionListener()
        	jBtn_Suite.setBounds(647, 463, 90, 25);
        }
        {
        	jBtn_UnAutre = new JButton();
        	javaPaint.add(jBtn_UnAutre);
        	jBtn_UnAutre.setText("Un autre!");
        	jBtn_UnAutre.setBounds(647, 423, 90, 29);
        }
        {
        	Pellicule = new Canvas();
        	javaPaint.add(Pellicule);
        	Pellicule.setBounds(32, 458, 596, 132);
        	Pellicule.setBackground(new java.awt.Color(255,255,255));
        }
        {
        	jBtn_Tourner = new JButton(new ImageIcon("IconTourner.gif"));
        	javaPaint.add(jBtn_Tourner);
                jBtn_Tourner.setText("Tourner");
        	jBtn_Tourner.addActionListener(new tourner());
        	jBtn_Tourner.setBounds(32, 226, 41, 34);
        }
        {
        	jBtn_ZoomMoins = new JButton(new ImageIcon("IconMoins.gif"));
        	javaPaint.add(jBtn_ZoomMoins);
                jBtn_ZoomMoins.setText("moins");
        	jBtn_ZoomMoins.addActionListener(new zoommoins());
        	jBtn_ZoomMoins.setBounds(96, 227, 35, 33);
        }
        {
        	jBtn_ZoomPlus = new JButton(new ImageIcon("IconPlus.GIF"));
        	javaPaint.add(jBtn_ZoomPlus);
                javaPaint.setText("plus");
        	jBtn_ZoomPlus.addActionListener(new zoomplus());
        	jBtn_ZoomPlus.setBounds(157, 227, 34, 33);
        }
        {
        	jLabel_Titre = new JLabel();
        	javaPaint.add(jLabel_Titre);
        	jLabel_Titre.setText("Titre du dessin");
        	jLabel_Titre.setBounds(385, 367, 96, 14);
        }
        {
        	jTxt_titreDessin = new JTextField();
        	javaPaint.add(jTxt_titreDessin);
        	jTxt_titreDessin.setBounds(350, 387, 198, 21);
        }
        {
        	VisuDess =new UTIL_VisuImage("banane.jpg");
        	javaPaint.add(VisuDess);
        	VisuDess.setEnabled(false);
        	VisuDess.setBounds(96, 298, 125, 140);
        	VisuDess.setBackground(new java.awt.Color(255,255,255));
        }
 
        //Fenêtre principale
        javaPaint.setBackground(new java.awt.Color(250,232,197));
        javaPaint.setPreferredSize(new java.awt.Dimension(803, 643));
        //Table d'outils
        crayon	.setBackground(	Color.white);
        crayon.setBounds(13, 6, 81, 39);
	 	efface	.setBackground(	Color.white);
	 	efface.setBounds(13, 50, 81, 39);
	 	jBtn_selectImage.setBounds(12, 100, 78, 21);
		jBtn_selectImage.setBackground(Color.white);
	 	//Panneau
 
	 		panneau.add(crayon);
	 		panneau.add(efface);
	 		panneau.add(jBtn_selectImage);
	 		jBtn_selectImage.setText("Image");
 
 
	 	//À la fermeture de la fenêtre
       addWindowListener(new WindowAdapter(){
        public void windowClosing(WindowEvent w)
        {System.exit(0);}});}
 
 
//Les classes qui implementent ActionListener:
//////////////////// FORME ////////////////////
 
class crayon implements ActionListener{                      
         public void actionPerformed(ActionEvent e) {
                     unDessin.figure=1;
                     }
                         }                                             
 
class efface implements ActionListener{                        
         public void actionPerformed(ActionEvent e) {               
                 unDessin.figure=3;
                }
 
                     }
 
 
class insertimage implements ActionListener{                        
    public void actionPerformed(ActionEvent e) {               
            unDessin.figure=4;
 
            }
	}
class tourner implements ActionListener{                        
    public void actionPerformed(ActionEvent e) {  
    	Angle=(Angle+1)%12;
    	VisuDess.setAngle(Angle);	
    	unDessin.setAngle(Angle);
 
    }
	}
class zoomplus implements ActionListener{                        
    public void actionPerformed(ActionEvent e) {
    	if(Xplus< 15 && Yplus<15)
    	{Xplus+=5;Yplus+=5;}
    	VisuDess.setMarge(Xplus,Yplus);
    	unDessin.setMarge(Xplus,Yplus);
            }
	}
class zoommoins implements ActionListener{                        
    public void actionPerformed(ActionEvent e) {  
    	if(Xplus>-15 && Yplus>-15)
    	{Xplus-=5;Yplus-=5;}
    	VisuDess.setMarge(Xplus,Yplus);
    	unDessin.setMarge(Xplus,Yplus);
    }
	}
 
///// MAIN /////
public static void main(String[] arg) throws IOException   {
             FCourbe javaPaint	=new FCourbe();
             javaPaint			.setSize		(800,620);
             javaPaint			.setLocation	(150,150);
             javaPaint			.setVisible		(true);
             javaPaint			.setLocationRelativeTo(null);
 
            }
 
}

Ensuite vient le petit canvas qui permet de visualiser l'image à coller:
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
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import java.awt.Canvas;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
 
import javax.imageio.ImageIO;
 
@SuppressWarnings("serial")
public class UTIL_VisuImage extends Canvas
  {
 
	BufferedImage  image;
    int Xplus,Yplus,Angle;
  public UTIL_VisuImage(String url) throws IOException
    {
    image = ImageIO.read(new File(url));
    prepareImage(image, this);
    }
 
  public void paint(Graphics g)
    {
	  Graphics2D g2d=(Graphics2D)g.create();
	  g2d.translate(10,15 );
	  if(0!=Angle)
	  {
		  for(int i=0;i<Angle;i++){
		  g2d.rotate(Math.PI/6);
    	  g2d.translate(18,-35 );}
	  }
 
 
    g2d.drawImage(image, 0, 0,image.getHeight()+Xplus,image.getWidth()+Yplus, this);
    g2d.dispose();
    }
 
  public boolean imageUpdate(Image image, int info, int x, int y, int l, int h)
  {
 
  if ((info & (ALLBITS)) != 0)
    {
    repaint();
    return false;
    }
  else
    {
    return true;
    }
  }
 
  public void setImage(String url) throws IOException{//pour changer l'image à afficher
 
	  image=ImageIO.read(new File(url));
 
	  prepareImage(image, this);
	  repaint();
  }
  public Image getImage(){ 
	  return image;
  }
 
public void setMarge(int xplus,int yplus) {
	Xplus = xplus;
	Yplus=yplus;
	repaint();
}	
 
public void setAngle(int angle) {
	Angle = angle;
	repaint();
}
 
 
  }

Suivit du grand canvas dans lequel je dessine :
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
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
 
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
import java.io.Serializable;
import java.util.Vector;
 
 
/*******************************************************/
/****************** CLASSE DESSIN **********************/
/*******************************************************/
@SuppressWarnings("serial")
public class UTIL_PAINT_Dessin extends Canvas implements MouseListener, MouseMotionListener{
 
	private int x1,y1,x2,y2,Xc,Yc;
     public int figure=0;
     int E=0;
     BufferedImage m,buf;
     Graphics2D g,g2d;
     @SuppressWarnings("unchecked")
	Vector v=new Vector();
     Color C=Color.black,temp,Cdep;
     FIGURE r;
     public String Texte;
     public Image monde=getToolkit().getImage("banane.jpg");
     boolean Charge=false;
 
    public int Xplus=0, Yplus=0, Angle=0;
 
//Le constructeur : 
@SuppressWarnings("deprecation")
public UTIL_PAINT_Dessin() {
 
         resize(500,250);
         setBackground(Color.white);
         setForeground(Color.white);
         addMouseListener(this);
         addMouseMotionListener(this);
 
                 }
 
 
public void update (Graphics g){
            paint(g);
}
@SuppressWarnings({ "deprecation" })
public void paint(Graphics gr){
 
         m=new BufferedImage(size().width,size().height, BufferedImage.TYPE_INT_ARGB);
         buf=new BufferedImage(size().width,size().height, BufferedImage.TYPE_INT_ARGB);
         g= (Graphics2D) m.getGraphics();
          g2d= (Graphics2D)buf.getGraphics();
         g2d.drawImage(monde,0,0,monde.getHeight(null),monde.getWidth(null),null);
 
//Dessin de tout les éléments du vecteur :       
for(int i=0;i<v.size();i++){       
             r=(FIGURE)v.elementAt(i);
                g.setColor(r.couleur);
 
            switch(r.figure){
 
                //Crayon
                case 1: g.drawLine(r.x,r.y,r.width,r.height);break;
                //pot de peinture
                case 2:
                break;
                //gomme
                case 3:temp=g.getColor();g.setColor(Color.white);g.fillOval(r.x,r.y,20,20);g.setColor(temp);
                break;
               //mettre une image
                case 4: 
 
 
                	g.drawImage(new UTIL_TourneImage(buf,r.Ang).getImage(),r.x,r.y,(int) (2.5*r.haut),(int) (2.5*r.larg),this);
                		break;
                            }
                }       
	g.setColor(C);
 
                gr.drawImage(m,0,0,this);
                g.dispose();
                gr.dispose();
 
                repaint();
    }
 
// Definition des méthodes de MouseListener et mouseMotionListener:     
 
 
	public void mousePressed(MouseEvent e) {
            e.consume();
            x1=e.getX();
            y1=e.getY();
            if(figure==1 || figure==3 )   {x2=x1; y2=y1;}
            ;
            }
    @SuppressWarnings("unchecked")
	public void mouseDragged(MouseEvent e) {
            e.consume();
            if(figure==1 || figure==3 )   { x1=x2;     y1=y2;}
            x2=e.getX();
            y2=e.getY();
            if(figure==1 || figure==3 )	v.addElement(new FIGURE(x1,y1,x2,y2,figure,C));
 
            }
    @SuppressWarnings("unchecked")
	public void mouseReleased(MouseEvent e) {
            e.consume();
            x2=e.getX();
            y2=e.getY();
            {v.addElement(new FIGURE(x1,y1,x2,y2,figure,C));}
            x2=x1;
            y2=y1;
    }
    public void mouseEntered(MouseEvent e){}
    public void mouseExited(MouseEvent e){}
    public void mouseMoved(MouseEvent e){}
 
	@SuppressWarnings("unchecked")
	public void mouseClicked(MouseEvent e){
		e.consume();
    	if(figure==2)// pot de peinture ou insertion image
    	{
    		Xc=e.getX();
    		Yc=e.getY();
    		v.addElement(new FIGURE(Xc,Yc,Xc,Yc,figure,C));
			Cdep=C;  
    	}
    	if(figure==4)// pot de peinture ou insertion image
    	{
    		Xc=e.getX();
    		Yc=e.getY();
    		v.addElement(new FIGURE(Xc,Yc,Xc,Yc,figure,C, monde.getHeight(null)+Xplus, monde.getWidth(null)+Yplus,Angle));
			 Charge=true; 
    	}
 
    }
 
 
	public void setMonde(BufferedImage img){
		monde=img;
	}
//*******************************************************************/	
public BufferedImage getImageM()
{
	return m;
}
public void setMarge(int xplus,int yplus) {
	Xplus = xplus;
	Yplus=yplus;
 
}	
 
 
 
public void setAngle(int angle) {
	Angle = angle;
 
}
public void setImage(Image monde) {
	g2d.drawImage(monde,0,0,monde.getHeight(null),monde.getWidth(null),null);
 
}
 
}//end class
 
 
 
/************************************************/
/**************** CLASSE FIGURE *****************/
/************************************************/
@SuppressWarnings("serial")
class FIGURE extends Rectangle implements Serializable{
            Color couleur;
    int figure;
    int larg;
    int haut;    
    int Ang;
    public FIGURE(int x,int y,int w,int h,int f,Color c){
       super(x,y,w,h);
       figure=f;
       couleur=c;
 
    }
    // pour les images
    public FIGURE(int x,int y,int w,int h,int f,Color c, int la,int ha,int angle){
        super(x,y,w,h);
        figure=f;
        couleur=c;
        larg=la;
        haut=ha;
        Ang=angle;
    }
}
et enfin, une class qui me permet de tourner les images ( en en créant une nouvelle sur laquelle on dessine l'ancienne après rotation)
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
25
26
27
28
29
30
31
32
33
34
35
36
37
 
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
 
 
public class UTIL_TourneImage  {
 
	BufferedImage buf;
	Graphics2D g2d;
 
	public UTIL_TourneImage(BufferedImage im, int angle)
	{
		 buf=new BufferedImage(im.getWidth(null),im.getHeight(null), BufferedImage.TYPE_INT_ARGB);
		 g2d=(Graphics2D)buf.createGraphics();
		g2d.drawImage(im,0,0,im.getHeight(null),im.getWidth(null),null);
 
		if(angle!=0)
		{// rotation par pas de 30° puis on recentre l'image après chaque rotation
			for(int i1=0;i1<angle;i1++)
			{
				g2d.rotate(Math.PI/6.0);
				g2d.translate(18,-35 );
			}
 
		}
 
		g2d.drawImage(buf,0,0,null);
		g2d.dispose();
	}
	// reprendre l'image tournée
public BufferedImage getImage(){
 
	return  buf;
 
 
	}
}

Le problème vient de la class qui sert à générer des images pivotées je pense, mais je ne le vois pas...

Si vous avez des idées...