Я использую следующий код для рисования текста на NSImage
func drawText(image :NSImage) ->NSImage
{
let text = textdata
let font = NSFont(name:String(combo_font.stringValue), size: 50)
let imageRect = CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height)
let fontAttributes = [NSAttributedStringKey.font: font]
let fontsize = (text as NSString).size(withAttributes: fontAttributes)
let textRect = CGRect(x: (image.size.width/2-fontsize.width/2), y: image.size.height/2, width: fontsize.width, height: fontsize.height)
let textStyle = NSMutableParagraphStyle.default.mutableCopy() as! NSMutableParagraphStyle
let textFontAttributes = [
NSAttributedStringKey.font: font,
NSAttributedStringKey.foregroundColor: NSColor.white,
NSAttributedStringKey.paragraphStyle: textStyle
]
let im:NSImage = NSImage(size: image.size)
let rep:NSBitmapImageRep = NSBitmapImageRep(bitmapDataPlanes: nil, pixelsWide: Int(image.size.width), pixelsHigh: Int(image.size.height), bitsPerSample: 8, samplesPerPixel: 4, hasAlpha: true, isPlanar: false, colorSpaceName: NSColorSpaceName.calibratedRGB, bytesPerRow: 0, bitsPerPixel: 0)!
im.addRepresentation(rep)
im.lockFocus()
image.draw(in: imageRect)
text.draw(in: textRect, withAttributes: textFontAttributes)
im.unlockFocus()
return im
}
Чтобы предотвратить зависание пользовательского интерфейса, я выполняю длительную операцию в фоновом потоке
override func controlTextDidChange(_ obj: Notification) {
if(obj.object is NSTextField)
{
let textdata=obj.object as! NSTextField
if(txtfield.identifier?.rawValue=="txt_field")
{
self.textdata=self.txtbox.stringValue
DispatchQueue.global().async {
self.img_view.image=self.drawText(image: NSImage(byReferencingFile: self.selectedfilename)!);
}
}
}
}
При обработке изображения размером 391 КБ, процесс обновления пользовательского интерфейса занимает слишком много времени. Как я могу улучшить производительность. Мне просто нужно отобразить предварительный просмотр для пользователя, изменение размера изображения до меньшего размера также позволяет повысить производительность; тот же внешний вид должен быть достигнут и на изображении с полным разрешением, а также при последующей обработке.
Обновление: в отношении фоновой резьбы
let group = DispatchGroup()
group.enter()
self.progress_preview.isHidden=false
self.progress_preview.startAnimation(self)
DispatchQueue.global(qos: .background).async {
self.text = self.txt_text.stringValue
self.globaimage = self.drawText(image: NSImage(byReferencingFile: self.selectedfilename)!);
group.leave()
}
// does not wait. But the code in notify() gets run
// after enter() and leave() calls are balanced
group.notify(queue: .main) {
self.img_view.image=self.globaimage
self.progress_preview.isHidden=true
self.progress_preview.stopAnimation(self)
}