rotation d'une NSImage dans une NSImageView
Chacha
Membre
Salut,
J'aimerais afficher une image dans une NSImageView, mais en la faisant pivoter de 90°.
J'ai réussi de façon assez lourdingue : à coups de NSAffineTransform, et en recopiant l'image dans une nouvelle NSImage par un drawRect, ça marche. Mais bon...
Je pense qu'afficher une image pivotée, MacOS X doit savoir le faire pour moi, mais je ne comprends pas comment.
Dans Cocoa : tous les setRotation, setBoundsRotation, setFrameRotation, rotationByAngle... font pivoter la frame, certes, mais l'image contenue dedans n'y est pas tournée, elle reste droite; dommage !
Dans CoreGraphics, il y a apparemment tout ce qu'il faut avec les CGContextRotateCTM (), mais comment mixer cela avec une NSImage et des NSImageView ? Je n'arrive pas à détourner l'affichage de l'image pour le faire avec CoreGraphics.
Vous avez des pistes ?
+
Chacha
J'aimerais afficher une image dans une NSImageView, mais en la faisant pivoter de 90°.
J'ai réussi de façon assez lourdingue : à coups de NSAffineTransform, et en recopiant l'image dans une nouvelle NSImage par un drawRect, ça marche. Mais bon...
Je pense qu'afficher une image pivotée, MacOS X doit savoir le faire pour moi, mais je ne comprends pas comment.
Dans Cocoa : tous les setRotation, setBoundsRotation, setFrameRotation, rotationByAngle... font pivoter la frame, certes, mais l'image contenue dedans n'y est pas tournée, elle reste droite; dommage !
Dans CoreGraphics, il y a apparemment tout ce qu'il faut avec les CGContextRotateCTM (), mais comment mixer cela avec une NSImage et des NSImageView ? Je n'arrive pas à détourner l'affichage de l'image pour le faire avec CoreGraphics.
Vous avez des pistes ?
+
Chacha
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Voilà
+
Chacha
[edit]
Apparemment, il faut faire un
CGImageRelease(imageRef) à la fin
[/edit]
Je ne vous en montre pas plus pour le moment, car le code est un gros sac de n½uds (genre oxitan )
[Fichier joint supprimé par l'administrateur]
image est une variable de classe qui pointe l'image de la NSImageView. C'est bien ca ??
Ensuite, tu rajoute translateTransform a rotateTransform. C'est bien pour recentrer l'image ??
image=[self image]copy];
Oui, mais la technique avec Core Graphics est immensément plus rapide, car on ne crée pas une nouvelle image : on fait des rotations en temps réel !
NSImageView --> AnimatedImage --> ImageSuiteView
                 |
                 Â
> SpinningImageView
                                |
                               Â
> CurvedTextView
AnimatedImage est une classe abstraite qui gère le timer, la méthode appelée devant être implémentée dans les classes dérivées.
ImageSuiteView affiche les images contenues dans un dossier successivement, à la manière d'un film.
SpinningImageView effectue une rotation d'une image
CurvedTextView effectue une rotation d'un texte, en fait, celui-ci est d'abord converti en une image, c'est pour ça que cette classe dérive de SpinningImage. OK c'est pas la meilleur soluce si l'image fait tout l'écran Je me suis inspiré de l'exemple d'Apple CircleView.
La classe ScrollingTextView a été rajoutée suite au besoin d'oxitan de faire défiler un texte, ici j'utilise la classe AnimatedImage pour le timer, donc c'est un NSImageView, c'est bien sûr inutile, un simple NSView convient.
Les sources sont en javaÂ
Je ne pense pas que ça soit très difficile à adapter en ObjC, à part le truc de la classe abstraite, qui semble pas avoir d'équivalent direct...
AnimatedImageJava.Sources.zip
Pour mon logiciel de redimensionnement d'image, je veux rajouter la rotation. J'utilise ton code, mpergand. Et je galère un peu beaucoup (n'étant pas doué pour ce qui est du graphique).
Ce que j'ai c'est :
- L'image originale (ou redimensionnée si l'utilisateur l'a fait)
- une NSImageView
À un moment j'ai réussi à bien caler la rotation, cependant l'image devient tronquée, j'ai l'impression qu'en fait il se base sur la taille de l'image originale.
Edit : Apparemment j'ai trouvé le problème. En fait après avoir correctement analysé le code je me suis rendu compte que tu prenais la taille de l'image view. Et comme je l'avais calé à la taille de l'image originale ben forcément c'est tronqué. Donc je dois faire quoi pour éviter ça ? Je dois recalculer la taille par rapport à la rotation ?
[Fichier joint supprimé par l'administrateur]
Si la taille de ton NSImageView est figée, lorsque tu fais tourner ton image, tu dois lui réduire ses dimensions pour qu'elle ne soit pas tronquée.
En fait, calcule les dimensions du rectangle enveloppant ton image tournée, et c'est ce rectange qui doit correspondre avec les dimensions de la NSImageView. Tu calcul le rapport entre les 2, et tu fais une NSAffineTransform.
Y a du cosinus dans l'air
cosinus de travers,
ta vue tu peux pas la faire,
Sans un p'tit calcul derrière ...
Voici comment faire :
Supposons que le centre de l'image soient de coordonnées (0;0), l'angle de rotation theta, l'image de largeur w et de hauteur h.
Le point A de coordonnées (w/2;h/2) est un sommet du rectangle quand l'angle de rotation est 0 et, quel que soit r, un sommet de l'image encore non tournée. Maintenant, un peu de maths.
Soit B le l'image de A par la rotation d'angle theta et de centre (0;0) (la rotation qui tourne l'image comme eaglelouk veut le faire). On a donc B de coordonnés (A.x*cos(theta)-A.y*sin(theta); A.x*sin(theta)+B.y*cos(theta)).
Si vous relisez ce que j'ai dit, vous verrez que B est un des sommets de l'image tournée. Pour continuer, il faudrait faire la même chose avec un autre point. Maintenant que l'on a des coordonnées, on va pouvoir récupérer une partie du rectangle.
Pour faire court, voici le code :
Voili voilou
[edit]
Il est très beau ton inspecteur ::)
Merci ma foufoune (Encore merci pour l'inspecteur au fait )
Surtout que c'est très simple (bien plus que NSAffineTransform)Â : on sauve le contexte graphique, on applique des transformations, on dessine et on restaure le contexte.
ça devrait donner un truc du genre :
Et les cosinus et sinus peuvent retourner d'où ils viennent :P (ceci-dit, s'il faut calculer un "scale", il faut sans doute y passer...)