NSImage上的绘图文字很慢-如何提高性能?

问题描述 投票:-1回答:1

我使用以下代码在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)

         }
swift macos xcode-storyboard nsimage
1个回答
0
投票

每次更改文本时,都没有理由在UI中用文本重新创建图像,因为它可能非常庞大,所以它总是很沉重,这里最耗时的是处理图像本身。

用于解决方案单独的UI和最终图像生成。即,只需在图像(NSTextField)上添加带有设置参数(位置,约束,字体,样式等)的常规标签(平面NSImageView),并预先(在Storyboard,Xib等)中进行更新即可编辑时的UI TextField。并且只有一次,在导出时,将最终文本渲染为最终图像-预期导出对于用户来说是很长的操作,因此无需担心,并且可以显示一些进度。

顺便说一句,也可以使用图层,但这不是必需的。

© www.soinside.com 2019 - 2024. All rights reserved.