swfit之绘图

//创建与设备无关的

    //Gray

//    [NSColor colorWithCalibratedWhite:(CGFloat) alpha:(CGFloat)];

    //RGB

//    [NSColor colorWithCalibratedRed:<#(CGFloat)#> green:<#(CGFloat)#> blue:<#(CGFloat)#> alpha:<#(CGFloat)#>];

//    HSB

//    [NSColor colorWithCalibratedHue:<#(CGFloat)#> saturation:<#(CGFloat)#> brightness:<#(CGFloat)#> alpha:<#(CGFloat)#>];

    

    //创建与设备相关

    //Gray

//    [NSColor colorWithDeviceWhite:<#(CGFloat)#> alpha:<#(CGFloat)#>]

    //RGB

//    [NSColor colorWithDeviceRed:<#(CGFloat)#> green:<#(CGFloat)#> blue:<#(CGFloat)#> alpha:<#(CGFloat)#>]

    //HSB

//    [NSColor colorWithDeviceHue:<#(CGFloat)#> saturation:<#(CGFloat)#> brightness:<#(CGFloat)#> alpha:<#(CGFloat)#>]

    //CMYK

//    [NSColor colorWithDeviceCyan:<#(CGFloat)#> magenta:<#(CGFloat)#> yellow:<#(CGFloat)#> black:<#(CGFloat)#> alpha:<#(CGFloat)#>]

//颜色创建和不同空间转换示例

        let rgbColor = NSColor(calibratedRed: 1.0, green: 0.5, blue: 0.5, alpha: 1)

        let cmykColor = rgbColor.usingColorSpace(.genericCMYK)

        let grayColor = rgbColor.usingColorSpace(.genericGray)

//从系统获取颜色

1 从Color Well控件获取

@IBAction func colorAction(_ sender: Any) {

        let well = sender as! NSColorWell

        print("select color is (well.color)")

    }

2.从NSPanel控件获取

    @IBAction func changeColorButtonAction(_ sender: AnyObject) {

        let panel = NSColorPanel.shared

        panel.setTarget(self)

        panel.setAction(#selector(self.colorSelect(_:)))

        panel.orderFront(self)

    }

    @IBAction func colorSelect(_ sender: AnyObject){

        let panel = sender as! NSColorPanel

        panel.color

    }

//图像绘制

    override func draw(_ dirtyRect: NSRect) {

        super.draw(dirtyRect)

        //保持绘图状态

        let path = NSBezierPath(ovalIn: dirtyRect)

        NSGraphicsContext.saveGraphicsState()

        //设置新绘图属性

        NSColor.gray.setFill()

        NSBezierPath.defaultLineWidth = 2.0

        //绘图操作

        path.fill()

        //恢复回执状态

        NSGraphicsContext.restoreGraphicsState()

    }

//创建图像

    override func draw(_ dirtyRect: NSRect) {

        super.draw(dirtyRect)

        self.wantsLayer = true

        self.layer?.borderWidth = 1

        let canvas = NSImage(size: dirtyRect.size)

        canvas.lockFocus()

        dirtyRect.fill()

        NSBezierPath.stroke(dirtyRect)

        canvas.unlockFocus()

        canvas.draw(at: NSPoint(x: 0, y: 0), from: NSRect(x: 0, y: 0, 40, height: 40), operation: .sourceOver, fraction: 1.0)

    }

//macOS 1.8以上

override func draw(_ dirtyRect: NSRect) {

        super.draw(dirtyRect)

        let image = NSImage(size: dirtyRect.size, flipped: true) { (rect) -> Bool in

            NSColor.red.setFill()

            rect.fill()

            return true

        }

        image.draw(at: NSPoint(x: 0, y: 0), from: NSRect(x: 0, y: 0, 40, height: 40), operation: .sourceOver, fraction: 1.0)

    }

//屏幕图像捕获

    /***1

     *1获取视图显示缓存区中的image对象

     *2image对象转换为位图

     *3从位图获取图像数据

     *4将数据写入文件

     **/

    func saveImage() {

        let data = self.view.dataWithPDF(inside: self.view.bounds)

        //视图的image

        let viewImage = NSImage(data: data)

        //获取ImageRep

        let imageRep = NSBitmapImageRep(data: (viewImage?.tiffRepresentation)!)

        //图香压缩比设置

        let imageProps = [NSBitmapImageRep.PropertyKey.compressionFactor: Int(1.0)]

        //数据

        let imageData = imageRep?.representation(using: .png, properties: imageProps)

        //图片格式 .png tiff bmp gif jpeg png jpeg2000

        let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)

        let documentsDirectory = paths[0]

        //文件路径URL

        let fileURL = URL(fileURLWithPath: documentsDirectory).appendingPathComponent("image.png")

        //写入文件

        try?imageData?.write(to: fileURL)

    }

//阴影

class ShadowDrawView: NSView {

    override func draw(_ dirtyRect: NSRect) {

        super.draw(dirtyRect)

        //保存绘图状态

        NSGraphicsContext.saveGraphicsState()

        //定义阴影

        let theShadow = NSShadow()

        theShadow.shadowOffset = NSMakeSize(5.0, -5.0)

        theShadow.shadowBlurRadius = 2.0

        //阴影为蓝色

        theShadow.shadowColor = NSColor.blue.withAlphaComponent(0.3)

        //设置绘图使用阴影

        theShadow.set()

        //定义绘图的矩形(图形)

        let rect = NSInsetRect(dirtyRect, 40, 40)

        //设置填充颜色为红色

        NSColor.red.setFill()

        //绘制矩形

        NSBezierPath.fill(rect)

        //恢复绘图状态

        NSGraphicsContext.restoreGraphicsState()

    }

}

//渐变

class GradientView: NSView {

    override func draw(_ dirtyRect: NSRect) {

        super.draw(dirtyRect)

        self.drawLineGradient()

    }

    //draw(in path: NSBezierPath, angle:CGFloat)

    func drawLineGradient() {

        let bounds = self.bounds

        let clipShape = NSBezierPath()

        clipShape.appendRect(bounds)

        let aGradient = NSGradient(colorsAndLocations: (NSColor.red, 0.0),(NSColor.green, 0.5),(NSColor.blue

        , 1.0))

        aGradient?.draw(in: clipShape, angle: 90)

    }

    //

    //在当前上下文中指定起点终点options参数

    ///draw(from: NSPoint, to: NSPoint, options: NSGradient.DrawingOptions)

    func drawPointGradient() {

        let aGradient = NSGradient(colorsAndLocations: (NSColor.red, 0.0),(NSColor.green, 0.5),(NSColor.blue

            , 1.0))

        let centerPoint = NSPoint(x: 0, y: 0)

        let otherPoint = NSPoint(x: 0, y: 60)

        aGradient?.draw(from: centerPoint, to: otherPoint, options: .drawsBeforeStartingLocation)

//        drawsAfterEndingLocation

    }

    //以rect参数为裁剪区域绘制渐变

    //draw(in: NSRect, angle: CGFloat)

    func drawRectGradient() {

        let aGradient = NSGradient(colorsAndLocations: (NSColor.red, 0.0),(NSColor.green, 0.5),(NSColor.blue

            , 1.0))

        let rect = NSRect(x: 10, y: 10, 40, height: 40)

        aGradient?.draw(in: rect, angle: 90)

    }

}

 //径向渐变 从起点到终点

//draw(fromCenter startCenter: NSPoint, radius startRadius:CGFloat, toCenter endCenter: NSPoint, radius endRadius: CGFloat, options: NSGradient.DrawingOptions = [])

class RadialGradientView: NSView {

    override func draw(_ dirtyRect: NSRect) {

        super.draw(dirtyRect)

        self.drawFromCenter()

    }

    func drawFromCenter() {

        let bounds = self.bounds

        let aGradient = NSGradient(starting: NSColor.blue, ending: NSColor.green)

        let centerPoint = NSMakePoint(NSMidX(bounds), NSMidY(bounds))

        let otherPoint = NSMakePoint(centerPoint.x + 10, centerPoint.y + 10)

        aGradient?.draw(fromCenter: centerPoint, radius: 50, toCenter: otherPoint, radius: 5.0, options: NSGradient.DrawingOptions.drawsBeforeStartingLocation)

    }

    

    //(-1,-1)左下角 指定渐变起点

    //draw(in: NSRect, relativeCenterPosition: NSPoint)

    func drawRelativeCenterPostion() {

        let aGradient = NSGradient(colorsAndLocations: (NSColor.red, 0.0),(NSColor.green, 0.5),(NSColor.yellow, 0.75),(NSColor.blue

            , 1.0))

        let startPoint = NSMakePoint(1, -1)

        let bounds = self.bounds

        aGradient?.draw(in: bounds, relativeCenterPosition: startPoint)

    }

    //绘制指定的Path

    //draw(in: NSBezierPath, relativeCenterPosition: NSPoint)

    func drawInPath() {

        let aGradient = NSGradient(colorsAndLocations: (NSColor.red, 0.0),(NSColor.green, 0.5),(NSColor.yellow, 0.75),(NSColor.blue

            , 1.0))

        let startPoint = NSMakePoint(1, -1)

        let bounds = self.bounds

        

        let path = NSBezierPath()

        path.appendRect(bounds)

        aGradient?.draw(in: path, relativeCenterPosition: startPoint)

    }

}

绘图性能优化,对于视图上有大量图形需要更新

使用getRectsBeingDrawn方法获取要绘制的所有脏区域矩形rects,对每个区域rect判断是否在视图的更新区域dirtyRect范围内,如果在则绘制重绘对象

 override func draw(_ dirtyRect: NSRect) {

        super.draw(dirtyRect)

        let drawObjects = self.subviews

        var rects = UnsafePointer<NSRect>.init(bitPattern: 1)

        var count = Int.init()

        self.getRectsBeingDrawn(&rects, count: &count)

        for view in drawObjects {

            for i in 0..<count {

                if NSIntersectsRect(view.bounds, (rects?[i])!) {

                    view.draw(dirtyRect)

                }

            }

        }

    }

原文地址:https://www.cnblogs.com/sundaymac/p/10680715.html