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
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.
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.
les forums Nokia ont un article et un code sur Rotation d'Images en Java M'
prise en main du Mobile Graphique 2D pour J2ME: http://developers.sun.com/mobility/midp/articles/s2dvg/index.html
http://j2mepolish.org/javadoc/j2me/de/enough/polish/util/ImageUtil.html
Vous pouvez essayer http://www.j2mearmyknife.com/ . Il dispose de beaucoup d'effets visuels cool, y compris la rotation de l'image.
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.
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);
}