【发布时间】:2020-08-02 00:02:33
【问题描述】:
我使用以下代码在 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
}
为了防止 UI 冻结,我在后台线程中执行长时间运行的操作
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)!);
}
}
}
}
处理 391KB 大小的图像时,更新 UI 的过程需要很长时间。如何提高性能。我只需要向用户显示预览,将图像调整为更小的尺寸也是一种选择以提高性能;但在以后处理时,全分辨率图像也应达到相同的外观。
更新: 关于后台线程
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)
}
【问题讨论】:
-
@vadian 你能看看这个
-
你看过
CATextLayer吗? -
@OlhaPavliuk
CATextLayer可以用来在 NSImage 上绘图吗? -
如果您需要“导出”该 NSImage,则可能不需要。但是如果你只需要在图像上方显示一些文本,你可以添加CALayer而不使用任何渲染代码。
-
@OlhaPavliuk 我想知道如果使用旧代码在导出的图像上呈现相同的字体大小,字体大小是否会匹配。
标签: swift macos xcode-storyboard nsimage