2009-08-04 5 views
1

Ich versuche, ein Bild mit etwas Text mit PyObjC zu überlagern, während ich bestrebt bin, meine Frage zu beantworten, "Annotate images using tools built into OS X". Durch Bezugnahme auf CocoaMagic, ein RubyObjC Ersatz für RMagick, ich habe mit diesem kommen:Fehler beim Zeichnen von Text auf NSImage in 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) 

Wenn ich es laufen, bekomme ich diese:

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 

Suchen Sie in der Dokumentation für drawAtPoint: withAttributes: Es heißt: "Sie sollten diese Methode nur aufrufen, wenn ein NSView den Fokus hat." NSImage ist keine Unterklasse von NSView, aber ich hoffe, dass das funktioniert und etwas sehr ähnliches scheint im Ruby-Beispiel zu funktionieren.

Was muss ich ändern, damit dies funktioniert?

Ich schrieb den Code um und konvertierte ihn Zeile für Zeile in ein Objective-C Foundation Tool. Es funktioniert, ohne Probleme. [Ich würde mich freuen, wenn hier posten, wenn es einen Grund, dies zu tun.]

Die Frage ist dann, wie funktioniert:

[message_string drawAtPoint:point withAttributes:text_attributes]; 

unterscheiden sich von

message_string.drawAtPoint_withAttributes_(point, text_attributes) 

? Gibt es eine Möglichkeit zu sagen, welche "OC_PythonObject" die NSInvalidArgumentException auslöst?

Antwort

1

Hier sind die Probleme in dem obigen Code:

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) 

Minor Tippfehler in der Tat.

Beachten Sie, dass der mittlere Teil des Codes kann mit dieser mehr lesbaren Variante ersetzt werden:

# 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) 

Das erfuhr ich von zu NodeBox auf dem Quellcode schauen, die zwölf Zeilen psyphography.py und cocoa.py, insbesondere die Methoden save und _getImageData.

Verwandte Themen