Obtenir le contenu d'une vue sous forme d'image
laurris
Membre
Comme l'indique le titre, je souhaiterais obtenir le contenu d'une vue sous forme d'image.
J'ai bien trouvé ceci http://www.cocoadev.com/index.pl?GettingViewContentAsImage sur Cocoadev sans être convaincu toutefois (trop compliqué).
Connaissez-vous un moyen plus simple ?
Mes respects,
Laurris.
Edit: je précise que j'ai lu ce topic de Bru: http://www.objective-cocoa.org/forum/index.php?topic=1556.0. Si possible, j'aimerais ne pas utiliser des fonctions non-documetées et si possible en Objective-C. Si pas possible j'utiliserai le code de Bru qui m'a l'air très efficace.
J'ai bien trouvé ceci http://www.cocoadev.com/index.pl?GettingViewContentAsImage sur Cocoadev sans être convaincu toutefois (trop compliqué).
Connaissez-vous un moyen plus simple ?
Mes respects,
Laurris.
Edit: je précise que j'ai lu ce topic de Bru: http://www.objective-cocoa.org/forum/index.php?topic=1556.0. Si possible, j'aimerais ne pas utiliser des fonctions non-documetées et si possible en Objective-C. Si pas possible j'utiliserai le code de Bru qui m'a l'air très efficace.
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Oui, en fait il y a une fonction toute faite pour cela. Le code de Bru est utile pour les fenêtres, mais pour les vues, tu peux regarder du côté de
Cette fonction te renvoie le contenu de la vue sous forme de données PDF.
Exemple d'utilisation :
+
Chacha
J'essaie de faire du drag'n drop de NSView et tu viens de me rendre un fier service !
Ce sujet linkait d'ailleurs un autre ici : http://www.objective-cocoa.org/forum/index.php?topic=1654.msg16730#msg16730
En gros, si ta vue n'a pas de sous-vue, la bonne solution est de faire :
Sinon, la méthode de Chacha, mais qui semble "lente" d'après les témoignages. ("la conversion en data qui a l'air un peu gourmande")
Voui, en général c'est foireux quand il y a des sous-vues (subviews)...
Comme une NSCell est une sous-vue d'un contrôle, ça ne passe pas (ça dessine le contenu de la vue principale, mais pas des sous-vues)...
J'avais tenté d'écrire une fonction qui dessinait récursivement les vues et sous-vues, mais manquait les focus et autres effets pour une obscure raison.
Oui c'est vrai... C'était les NSCell qui étaient mal dessinées dans ma fonction récursive en fait...
Ceci dit, elles ont tout de même une fonction :
Donc il doit y avoir moyen d'arranger ça.
Tu veux dire qu'il n'y a pas moyen de dessiner correctement une NSCell dans une image ?
Il y a peut-être quelques complications avec NSTableView qui a une seule NSCell par colonne re-dessinée pour chaque ligne.
Donc tout ça pour dire que la méthode que tu as proposé ne cause pas de problèmes si on l'applique dans une vue où on contrôle absolument tout, mais qu'il faut la considérer comme aléatoire lorsqu'il y a un élément qu'on a pas codé soi-même (ou pour lesquels on a pas accès aux sources).
*bon, si tu veux les détails:
Les cells en questions sont (notamment) les sous classes de NSActionCell, autrement dit, les contrôles. Ces classes utilisent l'Appearance Manager pour le dessin dans leur implémentation, ce sont donc des fonctions Carbon, qui doivent prendre comme argument un CGContextRef. Pour obtenir ce contexte dans l'implémentation de ces cells, elles prennent de NSGraphicsContext associé à la fenêtre de la vue passé en argument de [tt]drawWithFrame:inView:[/tt], et dessinent directement dedans. Donc avec la méthode que tu donnes, ça ne peut pas marcher, car les éléments qui dépendent de l'Appearance Manager sont dessiné dans le contexte de la fenêtre, et ce qui n'en dépend pas est dessiné dans le contexte courant, qui est alors l'image.
Mais ce cas pourrait aussi se présenter pour certains cells qui utilisent dans leur implémentation des appels directs à CoreGraphics. Et dans la mesure où Cocoa ne permet pas de faire tout ce que CoreGraphics permet (bête exemple: les dégradés), des appels à CoreGraphics ne sont pas à exclure dans l'implémentation de certaines sous-classes de NSCell et donc le fonctionnement de la méthode que tu donnes n'est pas garanti. ça peut fonctionner si le contexte est obtenu avec [tt][NSGraphicsContext currentContext][/tt], mais pas si le contexte est obtenu en prenant celui de la fenêtre de la vue.
Okay, je comprends mieux !
Il faudrait en fait une méthode "- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView context:(CGContextRef)context" (qui n'existe pas, et donc c'est râpé...)
Par contre, j'obtiens ceci dans la console. On dirait que des méthodes CG dépréciées sont appelées à travers cette méthode alors que la doc ne n'indique pas la méthode mère comme elle-même dépréciée. Et CGPDFPageGetBoxRect, est-ce qu'il serait possible de l'appeler directement pour contourner le problème ...
Selon toute logique, lors d'un appel à dataWithPDFInsideRect, la vue est redessinée (drawRect est appelé). Es-tu sûr que ce n'est pas dans ce code de dessin, que CGPDFDocumentGetMediaBox est appelé ?
+
Chacha
Donc c'est le initWithData avec des données PDF qui provoque cet appel et il est loin d'être direct, donc pour remplacer...
Par contre, chez moi, rien n'indique que cette fonction est "deprecated"... T'as activé une option ou une macro spéciale pour voir ça ? (j'ai bien "Warn About Deprecated Functions" de coché dans les "Build settings")
(car effectivement, elle est "deprecated" depuis 10.3)