La transformation d'un rectangle de l'image d'un quadrilatère à l'aide d'un CATransform3D
J'ai une image et d'un ensemble de quatre points (décrivant un quadrilatère Q). Je veux transformer cette image, de sorte qu'il s'adapte à la forme de quadrilatère Q. Photoshop appelle cette transformation "et de la distorsion." Mais, selon la source de ce quadrilatère (le point de vue de l'image en mouvement dans l'espace), il est en fait la combinaison d'une échelle, d'une rotation et d'un point de vue de la matrice.
Je me demande si c'est possible à l'aide d'un CATransform3D matrice 4x4. Avez-vous des conseils sur la façon de le faire? J'ai essayé de prendre les quatre points et construire 16 équations (de A' = A x u) mais il ne fonctionne pas: je ne suis pas sûr de ce que je dois utiliser comme z, z', w et w' coefficients...
L'image ci-dessous montre ce que je veux faire:
Voici quelques exemples de points:
276.523, 236.438, 517.656, 208.945, 275.984, 331.285, 502.23, 292.344
261.441, 235.059, 515.09, 211.5, 263.555, 327.066, 500.734, 295
229.031, 161.277, 427.125, 192.562, 229.16, 226, 416.48, 256
- Je ne pense pas que vous allez trouver une meilleure réponse à ce que KennyTM sur la question similaire, l'iPhone l'image s'étendant (skew). Le math il nous présente, il devrait être suffisant pour créer un arbitraire quadrilatère comme un résultat de l'application d'un CATransform3D à un CALayer.
- pour une raison étrange, la réponse de KennyTM ne semble pas fonctionner. Nous obtenons une matrice 3D, mais il donne mannequin résultats lorsqu'ils sont administrés à CoreAnimation...
- Ce faisant inverse de la transformation de l'quadrilatère à rect?
- Je pense que le
cvFindHomography()
OpenCV fonction également de travailler de cette façon. - et les autres, KennyTM est incroyable de code à partir de 5 ans, il est certainement un peu une corvée pour se rendre au travail dans la pratique, car il existe une certaine confusion avec ABCD rapport à l'ABDC de la commande, la traduction, etc ... dieu merci, JoshRL ci-dessous a fait tout le travail dur et créé un parfait abandon de classe basée sur la KTM de mathématiques. Il y a maintenant une Swift version qui fonctionne parfaitement et est testé beaucoup de choses stackoverflow.com/a/18606029/294884
Vous devez vous connecter pour publier un commentaire.
J'ai créé un kit pour le faire sur iOS: https://github.com/hfossli/AGGeometryKit/
Assurez-vous que votre point d'ancrage est en haut à gauche (
CGPointZero
).Je ne prends pas de crédit pour ce code. Tout ce que je fait a été à récurer l'internet et mis en place diverses réponses incomplètes.
Nous avons enfin obtenu ce travail. Nous avons essayé plusieurs méthodes, mais la plupart ont été un échec. Et certains ont même de la récupération d'une non identité de la matrice au moment de donner les mêmes points d'entrée et de sorties (par exemple, l'un de KennyTM... nous nous devons d'avoir manqué quelque chose là-bas).
À l'aide de OpenCV suivant, nous obtenons un
CATransform3D
prêt à être utilisé sur un CAAnimation couche:anchorPoint
le coin en haut à gauche (transform
est appliquée par rapport àanchorPoint
).cv::getPerspectiveTransform
. Les éléments de la matrice renvoyée par les deux cette fonction etcv::findHomography
sont de typedouble
pasfloat
comme indiqué ci-dessus.anchorPoint
spécificité! Et merci pour ledouble
vsfloat
valeur de retour, je n'avais pas remarqué. Mais quelle est exactement la différence entrecv::findHomography
etcv::getPerspectiveTransform
?Ici est un exemple de projet qui applique le code de hfossli la réponse ci-dessus et crée une catégorie sur UIView qui fixe le cadre et applique les transformer en un seul appel:
https://github.com/joshrl/FreeTransform
UIView+Quadrilatère code :
À 100% grâce à JoshRL, voici une Swift version de JoshRL de la classe.
Cela a été complètement et totalement débogué. Les lignes qui souffrent le "trop longtemps dans Swift" question ont été refait et la destruction testé. Il fonctionne parfaitement dans le haut volume de production.
Ne pouvait pas être plus facile à utiliser. Exemple montrant comment utiliser rapide ci-dessous.
2016 Swift version... plein, de travail, de copier et de coller solution
À utiliser dans Swift:
dire que vous avez un conteneur de vue "QuadScreen".
La vue que vous voulez étirer sera un JoshQuadView. Déposez-le dans la scène. Connecter à la IBOutlet, "jqv" dans l'exemple ici.
Simplement mis quatre coin-poignées (c'est à dire, les images) dans la scène, étant Png de votre poignée d'icônes. Lien vers la quatre IBOutlets pour les poignées. Le code juste complètement les poignées de ces poignées. (Suivez les commentaires dans le code pour pouvoir facilement les mettre en place dans le storyboard.)
Alors, c'est juste une ligne de code pour faire les étirements:
Comme une curiosité, et pour l'amour de google, il est ridiculement facile de faire cela dans
Android
ils ont une commande intégrée pour la restructuration de polys. Cette excellente réponse a copier et coller le code: https://stackoverflow.com/a/34667015/294884
POINT d'ANCRAGE INDÉPENDANT Solution:
J'aime vraiment @joshrl réponse où il fait une catégorie "UIView+Quadrilatère" qui utilise @hfossli de plus excellente réponse ci-dessus. Cependant, plusieurs appels à la catégorie à modifier le quadrilatère échoue, et le code exige la AnchorPoint être en haut à gauche.
Ma solution (dérivé de la sienne):
UIView+Quadrilatère.h:
UIView+Quadrilatère.m:
La catégorie ci-dessus est donc simple et élégant, il doit être inclus dans chaque boîte à outils. MERCI pour les sources ultimes de le code ci-dessus. Aucun crédit ne doit être donné à moi.
transformToFitQuadTopLeft
avec la plaine superview coordonnées et c'est tout. la Swift version fonctionne aussi parfaitement pour info. Merci encore aussi! CheersSi votre nouveau quadrilatère est un parallélogramme, alors cela s'appelle le "cisaillement," et peut être fait plus facilement avec CGAffineTransform. Voir Jeff LaMarche à l'excellent article de CGAffineTransform 1.1.
Si votre nouveau quadrilatère n'est pas un parallélogramme, alors reportez vous à la question suivante pour savoir comment appliquer CATransform3D: iPhone l'image s'étendant (skew).
À l'aide intégrée dans Swift matrice mathématique:
https://github.com/paulz/PerspectiveTransform#swift-code-example
@hfossli réponse (acceptée et plus voté réponse) est le calcul de la finale de la matrice de transformation, qui est "magique", qui est compliqué et illisible en aucune façon, et je pense que, sans réelle raison.
Ce que vous devez faire est de les transformations suivantes:
(L'ordre est important - vous devez avoir la mise à l'échelle la plus droite, et la traduction la plus à gauche).
Et puis inverser la matrice.
(Ou vous pouvez déjà calculer l'inverse de la matrice par l'inversion de l'ordre, et faire le contraire de transformations (la traduction dans la direction opposée, en tournant en face de l'angle et l'échelle en raison inverse de la taille). )
Dans iOS, j'imagine que ça va être quelque chose le long des lignes de:
où vous remplissez
....
avec la mise à l'échelle, la rotation et la translation nécessaire.