Algorithme de rotation des images

je cherche un algorithme qui fait tourner une image de quelques degrés (entrée).

public Image rotateImage(Image image, int degrees)

(les instances D'Image peuvent être remplacées par int[] contenant chaque pixel des valeurs RVB, Mon problème est que je dois l'implémenter pour un projet JavaME MIDP 2.0, donc je dois utiliser du code exécutable sur JVM avant la version 1.5. Quelqu'un peut-il m'aider avec cela ?

EDIT: j'ai oublié de mentionner que je n'ai pas SVG APIs disponible et que j'ai besoin d'une méthode de rotation par degré arbitraire autre que 90 - 180- 270

aussi, pas de java.awt.* les forfaits sont disponibles sur MIDP 2.0

17
demandé sur gnat 2009-01-27 21:19:52

8 réponses

L'une des meilleures pages décrivant les algorithmes de rotation d'image que j'ai trouvé sur internet est liée à excellent bibliothèque leptonica. Alors que la bibliothèque leptonica elle-même est écrite en C et ne vous aidera pas, sa page sur les algorithmes de rotation des images:

http://www.leptonica.com/rotation.html

vaut certainement le coup d'être lu. Vous voudrez probablement mettre en œuvre quelque chose comme la Rotation par algorithme de cartographie de zone il décrit dans la deuxième partie de la page.

20
répondu earino 2009-01-27 19:35:27

solution générale: pour chaque pixel dans l'image de destination, prendre le pixel dans l'image source avec les coordonnées du pixel de destination, tourné dans la direction opposée.

Amélioration de la solution: la rotation ne donne généralement pas les coordonnées exactes des pixels. Faites une moyenne pondérée du pixel source avec ses voisins, en fonction du pourcentage qu'il les chevauche.

solution plus rapide pour les images binaires: Convertir l'image dans "exécute" des pixels d'avant-plan consécutifs. Ensuite, faites tourner les points terminaux de ces lignes et attirez-les dans la destination.

Normalement cela produit de légères lacunes dues à un arrondi d'un nombre entier, donc quand un ou les deux paramètres sont à plus de 10% d'un nombre entier, patch en dessinant deux lignes pour la ligne de source simple, en utilisant les coordonnées d'entier arrondies vers le haut et vers le bas.

si un paramètre est à moins de 10% et que l'autre ne l'est pas, les deux lignes formeront un 'V'. Si les deux lignes sont coupées de plus de 10%, les deux lignes formeront un "X".

ceci peut être fait par rapport à l'axe des abscisses ou à l'axe des ordonnées . Utiliser l'une avec le plus petit angle entre l'axe et l'angle de rotation. (C'est-à-dire: si l'angle de rotation se situe entre 45 et -45, utilisez l'axe des abscisses.)

solution encore plus rapide pour les images binaires: S'il y a moins de pixels d'arrière-plan que de pixels d'avant-plan, remplissez la destination avec l'avant-plan, et suivez ce qui précède algorithme avec pixels de fond.

7
répondu user20493 2009-02-24 22:00:19

les forums Nokia ont un article et un code sur Rotation d'Images en Java M'

3
répondu Stephen Denne 2009-01-27 18:38:20

LWUIT peut le faire et il est opensource. Je vous suggère d'y trouver le code.

1
répondu Honza 2009-01-27 21:08:42

Vous pouvez essayer http://www.j2mearmyknife.com/ . Il dispose de beaucoup d'effets visuels cool, y compris la rotation de l'image.

0
répondu 2009-06-29 09:59:13

Graphics2D et AffineTransform vous aideront à faire exactement ce que vous voulez. Plus Précisément, Graphics2D.drawImage (Image, AffineTransform) et AffineTransform.getRotateInstance. Vous pouvez également faire l'échelle, la traduction, et la tonte avec cela. Les deux classes ont été dans l'exécution depuis au moins 1.4 probablement plus tôt.

-2
répondu basszero 2009-01-27 18:26:14
  public Image rotateImage(Image img, float degrees){
   BufferedImage sourceBI = new BufferedImage(img.getWidth(null),img.getHeight(null),BufferedImage.TYPE_INT_ARGB);
   sourceBI.getGraphics().drawImage(img,0,0,null);
   AffineTransform at = new AffineTransform();
   at.rotate(degrees*Math.PI/180, sourceBI.getWidth()/2, sourceBI.getHeight()/2);
   BufferedImageOp bio = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);
   return bio.filter(sourceBI, null);
  }
-2
répondu dave 2011-02-04 16:20:12