Ошибка рисования текста на NSImage в PyObjC

Я пытаюсь наложить изображение на текст с помощью PyObjC, пытаясь ответить на мой вопрос, "Аннотировать изображения с помощью инструментов, встроенных в OS X". Ссылаясь на CocoaMagic, замену RubyObjC для RMagick, я придумал следующее:

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

Когда я запускаю его, я получаю следующее:

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

Глядя в документы для drawAtPoint:withAttributes:, он говорит: «Вы должны вызывать этот метод только тогда, когда NSView имеет фокус». NSImage не является подклассом NSView, но я надеюсь, что это сработает, и похоже, что-то очень похожее работает в примере с Ruby.

Что мне нужно изменить, чтобы это заработало?


Я переписал код, точно преобразовав его, строка за строкой, в инструментарий Objective-C Foundation. Работает, без проблем. [Я был бы рад опубликовать здесь, если есть причина для этого.]

Тогда возникает вопрос, как:

[message_string drawAtPoint:point withAttributes:text_attributes];

отличаться от

message_string.drawAtPoint_withAttributes_(point, text_attributes)

? Есть ли способ узнать, какой «OC_PythonObject» вызывает исключение NSInvalidArgumentException?


person Clinton Blackmore    schedule 04.08.2009    source источник


Ответы (1)


Вот проблемы в приведенном выше коде:

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)

Действительно мелкие опечатки.

Обратите внимание, что среднюю часть кода можно заменить этим более читаемым вариантом:

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

Я узнал об этом, просмотрев исходный код NodeBox, двенадцать строк psyphography.py и cocoa.py, особенно методы save и _getImageData.

person Clinton Blackmore    schedule 25.08.2009