2017-05-02 6 views
3

Je vais utiliser cet algorithme pour la rotation de l'image, mais je me suis rendu compte qu'il tourne seulement des carrés, pas des rectangles.Pourquoi ce code fait-il uniquement pivoter les carrés?

Quelqu'un pourrait-il savoir pourquoi?

principal code problème:

public static int[] rotate(double angle, int[] pixels, int width, int height) { 
    final double radians = Math.toRadians(angle); 

    final double cos = Math.cos(radians); 
    final double sin = Math.sin(radians); 

    final int[] pixels2 = new int[pixels.length]; 

    for(int pixel = 0; pixel < pixels2.length; pixel++) { 
     pixels2[pixel] = 0xFFFFFF; 
    } 

    for(int x = 0; x < width; x++) { 
     for(int y = 0; y < height; y++) { 
      final int centerx = width/2; 
      final int centery = height/2; 
      final int m = x - centerx; 
      final int n = y - centery; 
      final int j = ((int) (m * cos + n * sin)) + centerx; 
      final int k = ((int) (n * cos - m * sin)) + centery; 
      if(j >= 0 && j < width && k >= 0 && k < height){ 
       pixels2[ (y * width + x) ] = pixels[ (k * width + j) ]; 
      } 
     } 
    } 
    return pixels2; 
} 

application Contexte:

try { 
    BufferedImage testrot = ImageIO.read(new File("./32x32.png")); 

    int[] linearpixels = new int[testrot.getWidth() * testrot.getHeight()]; 
    int c = 0; 
    for(int i = 0; i < testrot.getWidth(); i++){ 
     for(int j = 0; j < testrot.getHeight(); j++){ 
      linearpixels[c] = testrot.getRGB(i, j); 
      c++; 
     } 
    } 

    int[] lintestrot = rotate(50, linearpixels, 32, 32); 
    BufferedImage image = new BufferedImage(70, 70, BufferedImage.TYPE_INT_RGB); 
    c = 0; 
    for(int i = 0; i < 32; i++){ 
     for(int j = 0; j < 32; j++){ 
      image.setRGB(i, j, lintestrot[c]); 
      c++; 
     } 
    } 

    File outputfile = new File("test002.bmp"); 
    ImageIO.write(image, "bmp", outputfile); 

} catch (IOException e1) { 
    e1.printStackTrace(); 
} 

Si vous modifiez à 33 largeur ou la hauteur du résultat erroné (mauvaise image).

+1

Une raison pour laquelle vous ne pourriez pas faire quelque chose [comme ceci] (http://stackoverflow.com/questions/37758061/rotate-a-buffered-image-in-java/37758533#37758533) à la place? – MadProgrammer

+0

Faire des algorithmes me donne plus de liberté, mais j'analyse déjà votre sujet et c'était utile, merci. –

+1

Vous changez les limites de votre boucle for à 33 ou autre chose aussi? –

Répondre

2

Votre algorithme fonctionne réellement. Le problème est avec vos boucles dans votre application de contexte. Parce que les pixels sont stockés dans l'ordre de trame, la boucle extérieure doit itérer à la hauteur et les itère de boucle interne à la largeur, par exemple:

for(int i = 0; i < testrot.getHeight(); i++){ 
    for(int j = 0; j < testrot.getWidth(); j++){ 
     linearpixels[c] = testrot.getRGB(j, i); //edit here, tested 
     c++; 
    } 
} 

Ensuite, si vous changez la hauteur à 40 par exemple:

int[] lintestrot = rotate(50, linearpixels, 32, 40); 

les boucles doivent changer comme ceci:

c = 0; 
for(int i = 0; i < 40; i++){ 
    for(int j = 0; j < 32; j++){ 
     image.setRGB(i, j, lintestrot[c]); 
     c++; 
    } 
} 

Notez que l'ordre est inversé dans les boucles (hauteur puis largeur) par rapport à l'appel de fonction (largeur, puis la hauteur).

+0

J'avais déjà observé ce comportement auparavant (d'autres boucles), je n'avais même pas essayé ça. Je vais traduire votre anglais pour comprendre la source du problème, merci beaucoup et je suis en train de tester. Samgak. –

+0

Testé et approuvé! La prochaine fois attention à var nom: "LINEARPIXELS" hehe. –