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));
}
}
}
} |
Partager