2010-11-26 20 views
0

Mise à jour
:-)
de Nevermind figured it out à l'aide bitmapImageRepForCachingDisplayInRect & cacheDisplayInRect:toBitmapImageRep:.
Je vais laisser la question ici pour la postérité, cependant.de la difficulté à faire une image bitmap PNG à partir d'un NSView


Je travaille sur une petite application qui, entre autres, a une sous-classe NSView qui attire un tas de bezierPaths. J'aimerais pouvoir enregistrer le résultat affiché en EPS ou PNG.

La vue est en cours d'élaboration dans une fenêtre hors écran (pour des raisons d'échelle), et même si elle renvoie les données EPS correctes, je ne peux pas sembler obtenir des données bitmap utiles de celui-ci.

EPS ne pose aucun problème (j'écris simplement le NSData de -dataWithEPSInsideRect: dans un fichier), mais je n'arrive pas à obtenir un bitmap PNG.

Si j'essayer d'appeler:

[self lockFocus]; 
NSBitmapImageRep* rep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:self.bounds]; 
[self unlockFocus]; 
return rep; 

à partir d'une méthode de catégorie I ont ajouté à NSView, je reçois des données PNG blanc inutiles sur quand j'essaie representationUsingType:NSPNGFileType properties:[NSDictionary dictionary].

Étrangement, si j'essaie d'appeler lockFocus/initBitmapWith ../ unlockFocus de en dehors la vue (ou ses méthodes de catégorie), je reçois une exception disant que la vue ou l'un de ses ancêtres est caché. Et bien, oui, c'est hors écran (la fenêtre hors écran a été initialisée avec report: NON, au fait, donc ça devrait peindre). Donc, je peux soit obtenir des données inutiles ou je peux obtenir une exception. Pas génial. Pour ajouter à ma confusion: Si je fais un NSImage contenant une représentation EPS, et un bitmap blanc (inutile), où les deux devraient être la taille des limites de la vue, la représentation bitmap est toujours 20 pixels/unités plus étroite que les limites. Aucune idée pourquoi! L'EPS est la bonne taille.

Comme tout cela peut être lié à la façon dont la fenêtre de offscreen créé, voici le code pour que (de la catégorie NSView)

- (NSWindow*)placeInOffscreenWindow { 
NSRect windowBounds = { { -1000.0 , -1000.0 } , self.bounds.size }; 
NSWindow *hiddenWindow = [[NSWindow alloc] initWithContentRect: windowBounds 
                 styleMask: NSTitledWindowMask | NSClosableWindowMask 
                  backing: NSBackingStoreNonretained 
                  defer: NO]; 

[[hiddenWindow contentView] addSubview:self]; 
return hiddenWindow; 
} 

Toutes les idées serait appréciée!

Répondre

2

a fini par utiliser bitmapImageRepForCachingDisplayInRect: & cacheDisplayInRect:toBitmapImageRep: à la place

+0

Oui, et voici une réponse qui donne au moins le code réel: http://stackoverflow.com/a/9545213/478742 – mojuba

+0

cela fonctionne-t-il aussi bien pour les vues sauvegardées en couches? –

1

Je vous suggère de créer un NSImage, de verrouiller le focus, de dire à l'affichage de dessiner ses limites, et de débloquer le focus, puis de le passer à un CGImageDestination pour écrire les données/fichiers PNG.

+0

@Hosey: Merci pour le conseil, mais j'ai fini à l'aide bitmapImageRepForCachingDisplayInRect: & cacheDisplayInRect: toBitmapImageRep: au lieu, et cela semble fonctionner très bien. Mais j'essaierai probablement aussi votre suggestion, juste pour apprendre quelque chose. En passant, j'utilise le script Rentzsch fait activer vos avertissements suggérés - merci! "Hardass mode" m'a donné une tonne d'idées pour refactoriser, donc tout est beaucoup plus agréable maintenant! Aussi, puisque je ne fais que commencer avec Obj-C/Cocoa, c'est une grosse, grande aide! – Flambino

+0

J'ai trouvé CGImageDestination plus fiable que la méthode 'representationUsingType: properties:' de NSBitmapImageRep, mais ils * devraient * faire le même travail.En ce qui concerne le message d'avertissement: De rien. H –

+0

@Hosey: Intéressant. Merci pour l'insider-tip :) – Flambino