Voici un algorithme pour effectuer une rotation d'image (sans manger les bords) en complétant le fond par du noir

Code java : 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
/**
 * 
 */
package millie.operator.geometric;
 
import millie.image.Image;
import millie.operator.commons.ImageOperator;
 
/**
 * @author florent
 *
 */
public class RotationOperator implements ImageOperator {
	private double degree;
 
	/**
         * @param degree l'angle en degré pour la rotation
         */
	public RotationOperator(double degree) {
		this.degree = degree;
	}
 
	  /**
           *réalise une rotation de l'image
           *
           * @param out l'image de sortie
           * @param in l'image d'entrée
           *
           * @throw IllegalArgumentException si le nombre de composantes de dest et de
           *  in ne sont pas égales
           *
           * A noter que l'image de sortie sera plus grand que celle d'entrée
           * afin de tout contenir. Le fond sera rempli par du noir
           */
	@Override
	public void compute(Image out, Image in) throws Exception {
		 if(out.getNumComponents() != in.getNumComponents())
			    throw new IllegalArgumentException("rotationOperator");
 
			  /* détermine la valeur en radian de l'angle*/
			  double angle_radian = -degree * Math.PI / 180.0;
 
			  /*pour éviter pleins d'appel, on stocke les valeurs*/
			  double tcos = Math.cos(angle_radian);
			  double tsin = Math.sin(angle_radian);
 
			  /*calcul de la taille de l'image de destination*/
			  int largeurdest= (int)  Math.ceil(in.getWidth() * Math.abs(tcos) + in.getHeight()* Math.abs(tsin));
			  int hauteurdest= (int)  Math.ceil(in.getWidth()* Math.abs(tsin) + in.getHeight() * Math.abs(tcos));
 
			  /*on redimensionne l'image*/
			  out.resize(largeurdest, hauteurdest);
 
			  /*calcul du centre des images*/
			  int mxdest = out.getWidth()/2;
			  int mydest = out.getHeight()/2;
			  int mx = in.getWidth()/2;
			  int my = in.getHeight()/2;
 
			  for(int canal=0; canal<in.getNumComponents(); canal++)
			    for(int j=0;j< out.getHeight();j++)
			      for(int i=0;i< out.getWidth();i++)
			      {
			        /* on détermine la valeur de pixel qui correspond le mieux pour la position
			         * i,j de la surface de destination */
 
			        /* on détermine la meilleure position sur la surface d'origine en appliquant
			         * une matrice de rotation inverse
			         */
 
			        int bx = (int) (Math.ceil(tcos * (i-mxdest) + tsin * (j-mydest) + mx));
			        int by = (int) (Math.ceil (-tsin * (i-mxdest) + tcos * (j-mydest) + my));
			        /* on vérifie que l'on ne sort pas des bords*/
			        if (bx>=0 && bx< in.getWidth() && by>=0 && by< in.getHeight())
			        {
			          out.setPixel(i,j, canal, in.getPixel(bx, by, canal));
			        }
			      }
	}
 
}





PRomu@ld : sources