一款以最新潮的方式来使用UIImage的swift插件

本文介绍如何在Swift项目中利用TGImage插件创建复杂的UI元素,包括各种形状、渐变色背景及边框等。通过示例代码展示了不同类型的图片处理技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、新建一个swift工程,pod init支持cocapods

2、pod search TGImage


3、在podfile中写入 一句

pod 'TGImage'

4、编写代码

//
//  ViewController.swift
//  TGImageDemo
//
//  Created by targetcloud on 2017/7/1.
//  Copyright © 2017年 targetcloud. All rights reserved.
//

import UIKit
import TGImage

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        let iv : UIImageView = UIImageView(image: UIImage.size(width: UIScreen.main.bounds.width, height: 20)
            .color(gradient: [.lightGray, .white], locations: [0, 1], from: CGPoint(x: 0, y: 1), to: CGPoint(x: 0, y: 0))
            .border(color: .gray)
            .border(width: 1)
            .corner(radius: 5)
            .image)
        iv.frame.origin = CGPoint(x: 0, y: 20)
        self.view.addSubview(iv)
        
        let iv2 : UIImageView = UIImageView(image: UIImage.size(width: UIScreen.main.bounds.width, height: 34)
            .color(.orange)
            .corner(bottomLeft: 10)
            .corner(bottomRight: 10)
            .image)
        iv2.frame.origin = CGPoint(x: 0, y: iv.frame.maxY+5)
        self.view.addSubview(iv2)
        
        let iv3 : UIImageView = UIImageView(image: UIImage.size(width: 100, height: 70)
            .color(gradient: [UIColor.randomColor(), .white], locations: [0, 1], from: CGPoint(x: 0, y: 0), to: CGPoint(x: 1, y: 0))
            .border(color: .darkGray)
            .border(width: 5)
            .border(alignment: .outside)
            .corner(topLeft: 1)
            .corner(bottomLeft: 20)
            .corner(topRight: 20)
            .corner(bottomRight: 30)
            .image)
        iv3.frame.origin = CGPoint(x: 0, y: iv2.frame.maxY+5)
        self.view.addSubview(iv3)
        
        let iv4 = UIImageView(image: UIImage.size(width: 100, height: 100)
            .color(gradient: [.green, .blue], locations: [0, 1], from: CGPoint(x: 0, y: 1), to: CGPoint(x: 0, y: 0))
            .border(gradient: [.red, .yellow], locations: [0, 1], from: CGPoint(x: 0, y: 0), to: CGPoint(x: 1, y: 0))
            .border(width: 5)
            .border(alignment: .outside)
            .corner(topLeft: 20)
            .corner(topRight: 50)
            .corner(bottomLeft: 50)
            .corner(bottomRight: 20)
            .image)
        iv4.frame.origin = CGPoint(x: 0, y: iv3.frame.maxY+5)
        self.view.addSubview(iv4)
        
        let iv5 = UIImageView(image: UIImage(named: "2")!.with(size: CGSize(width: 50, height: 20)) { context in
            UIColor.red.setFill()
            context.fillEllipse(in: CGRect(x: 0, y: 0, width: 20, height: 20))
        })
        iv5.frame.origin = CGPoint(x: 0, y: iv4.frame.maxY)
        self.view.addSubview(iv5)
        
        let iv6 = UIImageView(image: ({ () -> UIImage in
            let background = UIImage.size(width: 120, height: 120)
                .color(gradient: [.black, .white], locations: [0, 1], from: CGPoint(x: 0, y: 0), to: CGPoint(x: 0, y: 1))
                .corner(radius: 13.5)
                .image
            let circle = UIImage.size(width: 106, height: 106)
                .color(.white)
                .corner(radius: 50)
                .image
            let center = UIImage.size(width: 8, height: 8)
                .color(.black)
                .corner(radius: 3)
                .image
            let clock = background + circle + center
            return clock.with { context in
                context.setLineCap(.round)
                UIColor.black.setStroke()
                context.setLineWidth(2)
                context.move(to: CGPoint(x: clock.size.width / 2, y: clock.size.height / 2))
                context.addLine(to: CGPoint(x: clock.size.width / 2 - 5, y: 15))
                context.move(to: CGPoint(x: clock.size.width / 2, y: clock.size.height / 2))
                context.addLine(to: CGPoint(x: clock.size.width - 25, y: clock.size.height / 2 - 3))
                context.strokePath()
                UIColor.red.setStroke()
                context.setLineWidth(1)
                context.move(to: CGPoint(x: clock.size.width / 2 + 8, y: clock.size.height / 2 - 7))
                context.addLine(to: CGPoint(x: 26, y: clock.size.height / 2 + 35))
                context.strokePath()
                UIColor.red.setFill()
                let rect = CGRect(x: clock.size.width / 2 - 1, y: clock.size.height / 2 - 1, width: 3, height: 3)
                context.fillEllipse(in: rect)
            }
        })())
        iv6.frame.origin.y = iv5.frame.maxY
        self.view.addSubview(iv6)
        
        self.view.addSubview(({ () -> UIButton in
            let button = UIButton(frame: CGRect(x: 0, y: 0, width: 100, height: 44))
            button.setBackgroundImage(
                UIImage.resizable()
                    .color(.lightGray)
                    .border(gradient: [.red, .white], locations: [0, 1], from: CGPoint(x: 0, y: 0), to: CGPoint(x: 1, y: 1))
                    .border(width: 2)
                    .border(alignment: .outside)
                    .corner(radius: 8)
                    .image,
                for: .normal
            )
            button.frame.origin.y = iv6.frame.maxY+5
            return button
        })())
        
        let topLeftCorner = UIImageView(image:
            ({ () -> UIImage in
                return UIImage.size(width: UIScreen.main.bounds.width*0.5, height: 22)
                    .color(gradient: [UIColor.randomColor(), .white], locations: [0, 1], from: CGPoint(x: 0, y: 0), to: CGPoint(x: 1, y: 1))
                    .corner(topLeft: 10)
                    .image
            })())
        topLeftCorner.frame.origin.y = self.view.bounds.height - 44
        self.view.addSubview(topLeftCorner)
        
        let bottomLeftCorner = UIImageView(image:
            ({ () -> UIImage in
                return UIImage.size(width: UIScreen.main.bounds.width*0.5, height: 22)
                    .color(gradient: [.lightGray, .white], locations: [0, 1], from: CGPoint(x: 0, y: 0), to: CGPoint(x: 1, y: 1))
                    .corner(bottomLeft: 10)
                    .image
            })())
        bottomLeftCorner.frame.origin.y = self.view.bounds.height - 22
        self.view.addSubview(bottomLeftCorner)
        
        let iv7 = UIImageView(image: ({ () -> UIImage in
            let img = UIImage.size(width: 180, height: 50)
                .color(.black)
                .corner(radius: 5)
                .image
            let background = UIImage.size(width: 160, height: 40)
                .color(.white)
                .corner(radius: 5)
                .image
            let circle = UIImage.size(width: 8, height: 8)
                .color(.white)
                .corner(radius: 4)
                .image
                //.with(color: .red)
                .position(CGPoint(x: 2, y: 10))
            
            return img + background + circle
        })())
        iv7.frame.origin = CGPoint(x: UIScreen.main.bounds.width*0.5, y: iv2.frame.maxY+5)
        self.view.addSubview(iv7)
        
        let iv8 = UIImageView(image:
            ({ () -> UIImage in
                let circle = UIImage.size(width: 8, height: 8)
                    .color(.white)
                    .corner(radius: 4)
                    .image
                    .position(CGPoint(x: 5, y: 5))
                return UIImage.size(width: UIScreen.main.bounds.width*0.5, height: 44)
                    .color(gradient: [.red, .white], locations: [0, 1], from: CGPoint(x: 0, y: 0), to: CGPoint(x: 1, y: 1))
                    .corner(bottomRight: 20)
                    .image + circle
            })())
        iv8.frame.origin.x = iv7.frame.origin.x
        iv8.frame.origin.y = iv7.frame.maxY + 5
        self.view.addSubview(iv8)
        
        let iv9 = UIImageView(image:
            ({ () -> UIImage in
                let circle = UIImage.size(width: 8, height: 8)
                    .color(.white)
                    .corner(radius: 4)
                    .image
                    .position(CGPoint(x: UIScreen.main.bounds.width * 0.5 - 15, y: 5))
                return UIImage.size(width: UIScreen.main.bounds.width*0.5, height: 44)
                    .color(gradient: [.white, .lightGray], locations: [0, 1], from: CGPoint(x: 0, y: 0), to: CGPoint(x: 1, y: 1))
                    .corner(bottomLeft: 20)
                    .image + circle
            })())
        iv9.frame.origin.x = iv8.frame.origin.x
        iv9.frame.origin.y = iv8.frame.maxY + 5
        self.view.addSubview(iv9)
        
        let iv10 = UIImageView(image: ({ () -> UIImage in
            let img = UIImage.size(width: 180, height: 70)
                .color(.red)
                .corner(radius: 15)
                .image
            let circle = UIImage.size(width: 18, height: 18)
                .color(.white)
                .corner(radius: 9)
                .image
                .position(CGPoint(x: 10, y: 10))
            return img + circle
        })())
        iv10.frame.origin = CGPoint(x: UIScreen.main.bounds.width*0.5, y: iv9.frame.maxY+5)
        self.view.addSubview(iv10)
        
        let iv11 = UIImageView(image: ({ () -> UIImage in
            let img = UIImage.size(width: 180, height: 60)
                .border(color: .black)
                .border(width: 2)
                .corner(radius: 5)
                .image
            let pinecone = UIImage(named: "1")?.position(CGPoint(x: 10, y: 10))
            return img + pinecone!
        })())
        iv11.frame.origin = CGPoint(x: UIScreen.main.bounds.width*0.5, y: iv10.frame.maxY+5)
        self.view.addSubview(iv11)
        
        let iv12 = UIImageView(image: ({ () -> UIImage in
            return UIImage(named: "3")!.with({ context in
                UIColor.red.setFill()
                let rect = CGRect(x: 39, y: 37, width: 10, height: 10)
                context.fillEllipse(in: rect)
            })
        })())
        iv12.frame.origin = CGPoint(x: UIScreen.main.bounds.width*0.5, y: iv11.frame.maxY+5)
        self.view.addSubview(iv12)
        
        let iv13 = UIImageView(image: ({ () -> UIImage in
            var container = UIImage.size(width: 180, height: 20)
                .color(.clear)
                .image
            for i in 0..<7{
                let doti = UIImage.size(width: 20, height: 20)
                    .color(gradient: [UIColor.randomColor(), UIColor.randomColor()], locations: [0, 1], from: CGPoint(x: 0, y: 0), to: CGPoint(x: 1, y: 1))
                    .corner(radius: 10)
                    .image
                    .position(CGPoint(x: i * 20 + (i + 1) * 3, y: 0))
                container = container + doti
            }
            return container
        })())
        iv13.frame.origin = CGPoint(x: UIScreen.main.bounds.width*0.5, y: iv12.frame.maxY+5)
        self.view.addSubview(iv13)
        
        let iv14 = UIImageView(image: ({ () -> UIImage in
            var container = UIImage.size(width: 30, height: 120)
                .color(.clear)
                .image
            for i in 0..<4{
                let doti = UIImage.size(width: CGFloat(30 - i * 4), height: CGFloat(30 - i * 4))
                    .color(gradient: [UIColor.randomColor(), UIColor.randomColor()], locations: [0, 1], from: CGPoint(x: 0, y: 0), to: CGPoint(x: 1, y: 1))
                    .corner(radius: CGFloat(30 - i * 4) * 0.5)
                    .image
                    .position(CGPoint(x: i * 2, y: 30 * i + (i + 1) * 3))
                container += doti
            }
            return container
        })())
        iv14.frame.origin = CGPoint(x: UIScreen.main.bounds.width*0.5, y: iv13.frame.maxY+5)
        self.view.addSubview(iv14)
        
        let iv99 = UIImageView(image:
            ({ () -> UIImage in
                return UIImage.size(width: UIScreen.main.bounds.width*0.5, height: 44)
                    .color(gradient: [.white, UIColor.randomColor().withAlphaComponent(0.5)], locations: [0, 1], from: CGPoint(x: 0, y: 0), to: CGPoint(x: 1, y: 1))
                    .corner(topLeft: 20)
                    .image
            })())
        iv99.frame.origin.x = iv8.frame.origin.x
        iv99.frame.origin.y = self.view.bounds.height - 44
        self.view.addSubview(iv99)
    }


}

5、运行效果






插件实现代码

//
//  TGImage.swift
//  TGImage
//
//  Created by targetcloud on 2017/6/30.
//  Copyright © 2017年 targetcloud. All rights reserved.
//

import UIKit

public enum BorderAlignment {
    case inside
    case center
    case outside
}

public extension UIImage {
    public typealias ContextBlock = (CGContext) -> Void
    
    public class func with(width: CGFloat, height: CGFloat, block: ContextBlock) -> UIImage {
        return self.with(size: CGSize(width: width, height: height), block: block)
    }
    
    public class func with(size: CGSize, opaque: Bool = false, scale: CGFloat = 0, block: ContextBlock) -> UIImage {
        UIGraphicsBeginImageContextWithOptions(size, opaque, scale)
        let context = UIGraphicsGetCurrentContext()!
        block(context)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image ?? UIImage()
    }
    
    public func with(size: CGSize, opaque: Bool = false, scale: CGFloat = 0, block: ContextBlock) -> UIImage {
        return self + UIImage.with(size:size,opaque:opaque,scale:scale,block:block)
    }
    
    public func with(_ block: ContextBlock) -> UIImage {
        return UIImage.with(size: self.size, opaque: false, scale: self.scale) { context in
            let rect = CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height)
            self.draw(in: rect)
            block(context)
        }
    }
    
    public func with(color: UIColor) -> UIImage {
        return UIImage.with(size: self.size) { context in
            context.translateBy(x: 0, y: self.size.height)
            context.scaleBy(x: 1, y: -1)
            context.setBlendMode(.normal)
            let rect = CGRect(origin: .zero, size: self.size)
            context.clip(to: rect, mask: self.cgImage!)
            color.setFill()
            context.fill(rect)
        }
    }
    
    public class func size(width: CGFloat, height: CGFloat) -> TGImagePresenter {
        return self.size(CGSize(width: width, height: height))
    }
    
    public class func size(_ size: CGSize) -> TGImagePresenter {
        let drawer = TGImagePresenter()
        drawer.size = .fixed(size)
        return drawer
    }
    
    public class func resizable() -> TGImagePresenter {
        let drawer = TGImagePresenter()
        drawer.size = .resizable
        return drawer
    }
    
    private struct AssociatedKeys {
        static var TGImagePositionKey = "TGImagePositionKey"
    }
    
    public var position: CGPoint{
        get {
            return objc_getAssociatedObject(self, &AssociatedKeys.TGImagePositionKey) as? CGPoint ?? CGPoint.zero
        }
        set(newValue) {
            if self.position != newValue{
                self.willChangeValue(forKey: "position")
                objc_setAssociatedObject(self, &AssociatedKeys.TGImagePositionKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
                self.didChangeValue(forKey: "position")
            }
        }
    }
    
    public func position(_ point:CGPoint) -> UIImage{
        self.position = point
        return self
    }
}

extension UIColor{
    public class func randomColor() -> UIColor{
        return UIColor(red: CGFloat(arc4random_uniform(255))/255.0, green: CGFloat(arc4random_uniform(255))/255.0, blue: CGFloat(arc4random_uniform(255))/255.0, alpha: 1.0)
    }
}

public func + (leftImage: UIImage, rigthImage: UIImage) -> UIImage {
    return leftImage.with { context in
        
        let leftRect = CGRect(x: 0, y: 0, width: leftImage.size.width, height: leftImage.size.height)
        var rightRect = CGRect(x: 0, y: 0, width: rigthImage.size.width, height: rigthImage.size.height)
        
        if rigthImage.position.x > 0 || rigthImage.position.y > 0{
            rightRect.origin.x = rigthImage.position.x
            rightRect.origin.y = rigthImage.position.y
        }else if leftRect.contains(rightRect) {
            rightRect.origin.x = (leftRect.size.width - rightRect.size.width) / 2
            rightRect.origin.y = (leftRect.size.height - rightRect.size.height) / 2
        } else {
            rightRect.size = leftRect.size
        }

        //print("\(String(describing: rigthImage.position.x )) \(String(describing: rigthImage.position.y ))")
        rigthImage.draw(in: rightRect)
    }
}

public func += (leftImage:inout UIImage, rigthImage: UIImage) {
    leftImage = leftImage + rigthImage
}

open class TGImagePresenter{
    public enum Size {
        case fixed(CGSize)
        case resizable
    }
    
    fileprivate static let defaultGradientLocations: [CGFloat] = [0, 1]
    fileprivate static let defaultGradientFrom: CGPoint = .zero
    fileprivate static let defaultGradientTo: CGPoint = CGPoint(x: 0, y: 1)
    
    fileprivate var colors: [UIColor] = [.clear]
    fileprivate var colorLocations: [CGFloat] = defaultGradientLocations
    fileprivate var colorStartPoint: CGPoint = defaultGradientFrom
    fileprivate var colorEndPoint: CGPoint = defaultGradientTo
    fileprivate var borderColors: [UIColor] = [.black]
    fileprivate var borderColorLocations: [CGFloat] = defaultGradientLocations
    fileprivate var borderColorStartPoint: CGPoint = defaultGradientFrom
    fileprivate var borderColorEndPoint: CGPoint = defaultGradientTo
    fileprivate var borderWidth: CGFloat = 0
    fileprivate var borderAlignment: BorderAlignment = .inside
    fileprivate var cornerRadiusTopLeft: CGFloat = 0
    fileprivate var cornerRadiusTopRight: CGFloat = 0
    fileprivate var cornerRadiusBottomLeft: CGFloat = 0
    fileprivate var cornerRadiusBottomRight: CGFloat = 0
    
    fileprivate var size: Size = .resizable
    
    private static var cachedImages = [String: UIImage]()
    
    private var cacheKey: String {
        var attributes = [String: String]()
        attributes["colors"] = String(self.colors.description.hashValue)
        attributes["colorLocations"] = String(self.colorLocations.description.hashValue)
        attributes["colorStartPoint"] = String(String(describing: self.colorStartPoint).hashValue)
        attributes["colorEndPoint"] = String(String(describing: self.colorEndPoint).hashValue)
        attributes["borderColors"] = String(self.borderColors.description.hashValue)
        attributes["borderColorLocations"] = String(self.borderColorLocations.description.hashValue)
        attributes["borderColorStartPoint"] = String(String(describing: self.borderColorStartPoint).hashValue)
        attributes["borderColorEndPoint"] = String(String(describing: self.borderColorEndPoint).hashValue)
        attributes["borderWidth"] = String(self.borderWidth.hashValue)
        attributes["borderAlignment"] = String(self.borderAlignment.hashValue)
        attributes["cornerRadiusTopLeft"] = String(self.cornerRadiusTopLeft.hashValue)
        attributes["cornerRadiusTopRight"] = String(self.cornerRadiusTopRight.hashValue)
        attributes["cornerRadiusBottomLeft"] = String(self.cornerRadiusBottomLeft.hashValue)
        attributes["cornerRadiusBottomRight"] = String(self.cornerRadiusBottomRight.hashValue)
        
        switch self.size {
        case .fixed(let size):
            attributes["size"] = "Fixed(\(size.width), \(size.height))"
        case .resizable:
            attributes["size"] = "Resizable"
        }
        
        var serializedAttributes = [String]()
        for key in attributes.keys.sorted() {
            if let value = attributes[key] {
                serializedAttributes.append("\(key):\(value)")
            }
        }
        
        let cacheKey = serializedAttributes.joined(separator: "|")
        return cacheKey
    }
    
    open func color(_ color: UIColor) -> Self {
        self.colors = [color]
        return self
    }
    
    open func color(gradient: [UIColor],locations: [CGFloat] = defaultGradientLocations,from startPoint: CGPoint = defaultGradientFrom,to endPoint: CGPoint = defaultGradientTo) -> Self {
        self.colors = gradient
        self.colorLocations = locations
        self.colorStartPoint = startPoint
        self.colorEndPoint = endPoint
        return self
    }
    
    open func border(color: UIColor) -> Self {
        self.borderColors = [color]
        return self
    }
    
    open func border(gradient: [UIColor],locations: [CGFloat] = defaultGradientLocations,from startPoint: CGPoint = defaultGradientFrom,to endPoint: CGPoint = defaultGradientTo
        ) -> Self {
        self.borderColors = gradient
        self.borderColorLocations = locations
        self.borderColorStartPoint = startPoint
        self.borderColorEndPoint = endPoint
        return self
    }
    
    open func border(width: CGFloat) -> Self {
        self.borderWidth = width
        return self
    }
    
    open func border(alignment: BorderAlignment) -> Self {
        self.borderAlignment = alignment
        return self
    }
    
    open func corner(radius: CGFloat) -> Self {
        return self.corner(topLeft: radius, topRight: radius, bottomLeft: radius, bottomRight: radius)
    }
    
    open func corner(topLeft: CGFloat) -> Self {
        self.cornerRadiusTopLeft = topLeft
        return self
    }
    
    open func corner(topRight: CGFloat) -> Self {
        self.cornerRadiusTopRight = topRight
        return self
    }
    
    open func corner(bottomLeft: CGFloat) -> Self {
        self.cornerRadiusBottomLeft = bottomLeft
        return self
    }
    
    open func corner(bottomRight: CGFloat) -> Self {
        self.cornerRadiusBottomRight = bottomRight
        return self
    }
    
    open func corner(topLeft: CGFloat, topRight: CGFloat, bottomLeft: CGFloat, bottomRight: CGFloat) -> Self {
        return self.corner(topLeft: topLeft).corner(topRight: topRight).corner(bottomLeft: bottomLeft).corner(bottomRight: bottomRight)
    }
    
    open var image: UIImage {
        switch self.size {
        case .fixed(let size):
            return self.imageWithSize(size)
        case .resizable:
            self.borderAlignment = .inside
            let cornerRadius = max(self.cornerRadiusTopLeft, self.cornerRadiusTopRight,self.cornerRadiusBottomLeft, self.cornerRadiusBottomRight)
            let capSize = ceil(max(cornerRadius, self.borderWidth))
            let imageSize = capSize * 2 + 1
            let image = self.imageWithSize(CGSize(width: imageSize, height: imageSize))
            let capInsets = UIEdgeInsets(top: capSize, left: capSize, bottom: capSize, right: capSize)
            return image.resizableImage(withCapInsets: capInsets)
        }
    }
    
    private func imageWithSize(_ size: CGSize, useCache: Bool = true) -> UIImage {
        if let cachedImage = type(of: self).cachedImages[self.cacheKey], useCache {
            return cachedImage
        }
        
        var imageSize = CGSize(width: size.width, height: size.height)
        var rect = CGRect()
        rect.size = imageSize
        
        switch self.borderAlignment {
        case .inside:
            rect.origin.x += self.borderWidth / 2
            rect.origin.y += self.borderWidth / 2
            rect.size.width -= self.borderWidth
            rect.size.height -= self.borderWidth
        case .center:
            rect.origin.x += self.borderWidth / 2
            rect.origin.y += self.borderWidth / 2
            imageSize.width += self.borderWidth
            imageSize.height += self.borderWidth
        case .outside:
            rect.origin.x += self.borderWidth / 2
            rect.origin.y += self.borderWidth / 2
            rect.size.width += self.borderWidth
            rect.size.height += self.borderWidth
            imageSize.width += self.borderWidth * 2
            imageSize.height += self.borderWidth * 2
        }
        
        let cornerRadius = max(self.cornerRadiusTopLeft, self.cornerRadiusTopRight,self.cornerRadiusBottomLeft, self.cornerRadiusBottomRight)
        
        let image = UIImage.with(size: imageSize) { context in
            let path: UIBezierPath
            if self.cornerRadiusTopLeft == self.cornerRadiusTopRight && self.cornerRadiusTopLeft == self.cornerRadiusBottomLeft && self.cornerRadiusTopLeft == self.cornerRadiusBottomRight && self.cornerRadiusTopLeft > 0 {
                path = UIBezierPath(roundedRect: rect, cornerRadius: self.cornerRadiusTopLeft)
            } else if cornerRadius > 0 {
                let startAngle = CGFloat.pi
                let topLeftCenter = CGPoint(x: self.cornerRadiusTopLeft + self.borderWidth / 2,y: self.cornerRadiusTopLeft + self.borderWidth / 2)
                let topRightCenter = CGPoint(x: imageSize.width - self.cornerRadiusTopRight - self.borderWidth / 2,y: self.cornerRadiusTopRight + self.borderWidth / 2)
                let bottomRightCenter = CGPoint(x: imageSize.width - self.cornerRadiusBottomRight - self.borderWidth / 2,y: imageSize.height - self.cornerRadiusBottomRight - self.borderWidth / 2)
                let bottomLeftCenter = CGPoint(x: self.cornerRadiusBottomLeft + self.borderWidth / 2,y: imageSize.height - self.cornerRadiusBottomLeft - self.borderWidth / 2)
                let mutablePath = UIBezierPath()
                self.cornerRadiusTopLeft > 0 ? mutablePath.addArc(withCenter: topLeftCenter,radius: self.cornerRadiusTopLeft,startAngle: startAngle,endAngle: 1.5 * startAngle,clockwise: true) : mutablePath.move(to: topLeftCenter)
                self.cornerRadiusTopRight > 0 ? mutablePath.addArc(withCenter: topRightCenter,radius: self.cornerRadiusTopRight,startAngle: 1.5 * startAngle,endAngle: 2 * startAngle,clockwise: true) : mutablePath.addLine(to: topRightCenter)
                self.cornerRadiusBottomRight > 0 ? mutablePath.addArc(withCenter: bottomRightCenter,radius: self.cornerRadiusBottomRight,startAngle: 2 * startAngle,endAngle: 2.5 * startAngle,clockwise: true) : mutablePath.addLine(to: bottomRightCenter)
                self.cornerRadiusBottomLeft > 0 ? mutablePath.addArc(withCenter: bottomLeftCenter,radius: self.cornerRadiusBottomLeft,startAngle: 2.5 * startAngle,endAngle: 3 * startAngle,clockwise: true) : mutablePath.addLine(to: bottomLeftCenter)
                self.cornerRadiusTopLeft > 0 ? mutablePath.addLine(to: CGPoint(x: self.borderWidth / 2, y: topLeftCenter.y)) : mutablePath.addLine(to: topLeftCenter)
                path = mutablePath
            }
            else {
                path = UIBezierPath(rect: rect)
            }
            
            context.saveGState()
            if self.colors.count <= 1 {
                self.colors.first?.setFill()
                path.fill()
            } else {
                let colorSpace = CGColorSpaceCreateDeviceRGB()
                let colors = self.colors.map { $0.cgColor } as CFArray
                if let gradient = CGGradient(colorsSpace: colorSpace, colors: colors, locations: self.colorLocations) {
                    let startPoint = CGPoint(x: self.colorStartPoint.x * imageSize.width,y: self.colorStartPoint.y * imageSize.height)
                    let endPoint = CGPoint(x: self.colorEndPoint.x * imageSize.width,y: self.colorEndPoint.y * imageSize.height)
                    context.addPath(path.cgPath)
                    context.clip()
                    context.drawLinearGradient(gradient, start: startPoint, end: endPoint, options: [])
                }
            }
            context.restoreGState()
            
            context.saveGState()
            if self.borderColors.count <= 1 {
                self.borderColors.first?.setStroke()
                path.lineWidth = self.borderWidth
                path.stroke()
            } else {
                let colorSpace = CGColorSpaceCreateDeviceRGB()
                let colors = self.borderColors.map { $0.cgColor } as CFArray
                if let gradient = CGGradient(colorsSpace: colorSpace, colors: colors, locations: self.borderColorLocations) {
                    let startPoint = CGPoint(x: self.borderColorStartPoint.x * imageSize.width,y: self.borderColorStartPoint.y * imageSize.height)
                    let endPoint = CGPoint(x: self.borderColorEndPoint.x * imageSize.width,y: self.borderColorEndPoint.y * imageSize.height)
                    context.addPath(path.cgPath)
                    context.setLineWidth(self.borderWidth)
                    context.replacePathWithStrokedPath()
                    context.clip()
                    context.drawLinearGradient(gradient, start: startPoint, end: endPoint, options: [])
                }
            }
            context.restoreGState()
        }

        if useCache {
            type(of: self).cachedImages[self.cacheKey] = image
        }
        return image
    }
}

最新更新

https://github.com/targetcloud/TGImage



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值