2009-08-04 10 views
1

J'essaie de superposer une image avec du texte en utilisant PyObjC, tout en essayant de répondre à ma question, "Annotate images using tools built into OS X". En faisant référence à CocoaMagic, un remplacement RubyObjC pour RMagick, je suis venu avec ceci:Erreur de dessin du texte sur NSImage dans PyObjC

#!/usr/bin/env python 

from AppKit import * 

source_image = "/Library/Desktop Pictures/Nature/Aurora.jpg" 
final_image = "/Library/Desktop Pictures/.loginwindow.jpg" 
font_name = "Arial" 
font_size = 76 
message = "My Message Here" 

app = NSApplication.sharedApplication() # remove some warnings 

# read in an image 
image = NSImage.alloc().initWithContentsOfFile_(source_image) 
image.lockFocus() 

# prepare some text attributes 
text_attributes = NSMutableDictionary.alloc().init() 
font = NSFont.fontWithName_size_(font_name, font_size) 
text_attributes.setObject_forKey_(font, NSFontAttributeName) 
text_attributes.setObject_forKey_(NSColor.blackColor, NSForegroundColorAttributeName) 

# output our message 
message_string = NSString.stringWithString_(message) 
size = message_string.sizeWithAttributes_(text_attributes) 
point = NSMakePoint(400, 400) 
message_string.drawAtPoint_withAttributes_(point, text_attributes) 

# write the file 
image.unlockFocus() 
bits = NSBitmapImageRep.alloc().initWithData_(image.TIFFRepresentation) 
data = bits.representationUsingType_properties_(NSJPGFileType, nil) 
data.writeToFile_atomically_(final_image, false) 

Quand je cours, je reçois ceci:

Traceback (most recent call last): 
    File "/Users/clinton/Work/Problems/TellAtAGlance/ObviouslyTouched.py", line 24, in <module> 
    message_string.drawAtPoint_withAttributes_(point, text_attributes) 
ValueError: NSInvalidArgumentException - Class OC_PythonObject: no such selector: set 

Vous cherchez dans la documentation pour drawAtPoint: withAttributes: , il dit, "Vous ne devriez invoquer cette méthode quand un NSView a le focus." NSImage n'est pas une sous-classe de NSView, mais j'espère que cela fonctionnera, et quelque chose de très similaire semble fonctionner dans l'exemple de Ruby.

Que dois-je changer pour que cela fonctionne? J'ai réécrit le code en le convertissant fidèlement, ligne par ligne, en un outil Foundation Objective-C. Cela fonctionne, sans problèmes. [Je serais heureux de poster si ici s'il y a une raison de le faire.]

La question devient alors, comment:

[message_string drawAtPoint:point withAttributes:text_attributes]; 

diffèrent

message_string.drawAtPoint_withAttributes_(point, text_attributes) 

? Est-il un moyen de dire quel "OC_PythonObject" soulève l'exception NSInvalidArgumentException?

Répondre

1

Voici les problèmes dans le code ci-dessus:

text_attributes.setObject_forKey_(NSColor.blackColor, NSForegroundColorAttributeName) 
-> 
text_attributes.setObject_forKey_(NSColor.blackColor(), NSForegroundColorAttributeName) 

bits = NSBitmapImageRep.alloc().initWithData_(image.TIFFRepresentation) 
data = bits.representationUsingType_properties_(NSJPGFileType, nil) 
-> 
bits = NSBitmapImageRep.imageRepWithData_(image.TIFFRepresentation()) 
data = bits.representationUsingType_properties_(NSJPEGFileType, None) 

fautes de frappe mineures en effet.

Notez que la partie médiane du code peut être remplacé par cette variante plus lisible:

# prepare some text attributes 
text_attributes = { 
    NSFontAttributeName : NSFont.fontWithName_size_(font_name, font_size), 
    NSForegroundColorAttributeName : NSColor.blackColor() 
} 

# output our message 
NSString.drawAtPoint_withAttributes_(message, (400, 400), text_attributes) 

Je l'ai appris en regardant le code source à NodeBox, les douze lignes de psyphography.py et cocoa.py, en particulier les méthodes save et _getImageData.