SVG转UIImage图片

import Foundation

public class NodeDrawingEngine: NSObject {

    /// Scene root node
    open var node: Node = Group() {
        didSet {
            self.renderer?.dispose()
            self.renderer = RenderUtils.createNodeRenderer(node, view: nil)
        }
    }

    open var contentLayout: ContentLayout = .none

    open var contentMode: MViewContentMode {
        didSet {
            contentLayout = ContentLayout.of(contentMode: contentMode)
        }
    }

    var place: Transform {
        return placeManager.placeVar.value
    }

    var placeVar: Variable<Transform> {
        return placeManager.placeVar
    }

    open var size: CGSize
    open var opaque: Bool
    open var scale: CGFloat

    private let placeManager = RootPlaceManager()
    private let layoutHelper = EngineLayoutHelper()

    var context: EngineRenderContext!
    var renderer: NodeRenderer?
    
    open var backgroundColor: UIColor? = nil

    public init(size: CGSize, node: Node = Group(),  contentLayout: ContentLayout = .none, contentMode: MViewContentMode = .scaleAspectFit, renderer: NodeRenderer? = nil, backgroundColor: UIColor? = nil, scale: CGFloat = UIScreen.main.scale, opaque: Bool = false) {
        self.node = node
        self.contentMode = contentMode
        self.contentLayout = ContentLayout.of(contentMode: contentMode)
        self.size = size
        self.context = EngineRenderContext(size: size)
        self.renderer = renderer
        self.backgroundColor = backgroundColor
        self.scale = scale
        self.opaque = opaque
    }

    open func converNode(_ node: Node) -> MImage? {
        self.node = node
        let rect = CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height)
        UIGraphicsBeginImageContextWithOptions(rect.size, self.opaque, self.scale)
        context.cgContext = UIGraphicsGetCurrentContext()
        guard let ctx = context.cgContext else {
            return nil
        }
        if self.backgroundColor == nil {
            ctx.clear(rect)
        }
        guard let renderer = renderer else {
            return nil
        }
        placeManager.setLayout(place: layoutHelper.getTransform(renderer, contentLayout, self.size.toMacaw(), targetSize: self.size))
        ctx.concatenate(self.place.toCG())
        renderer.calculateZPositionRecursively()
        renderer.render(in: ctx, force: false, opacity: node.opacity)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image
    }
}

class EngineRenderContext {
    var size: CGSize?
    var cgContext: CGContext?

    init(size: CGSize?) {
        self.size = size
        self.cgContext = nil
    }
}

class EngineLayoutHelper {

    public func getTransform(_ nodeRenderer: NodeRenderer, _ layout: ContentLayout, _ size: Size, targetSize: CGSize? = nil) -> Transform {
        let node = nodeRenderer.node
        var rect = node.bounds
        if let canvas = node as? SVGCanvas {
            if let targetSize = targetSize {
                rect = canvas.layout(size: targetSize.toMacaw()).rect()
            } else {
                rect = BoundsUtils.getNodesBounds(canvas.contents)
            }
        }
        if let rect = rect {
            return layout.layout(rect: rect, into: size)
        }
        return Transform.identity
    }

}

代码功能为将 SVG 图像转为 UIImage 对象,利用了流行 svg swift 库

posted @ 2023-03-11 00:40  雨筱逸悠  阅读(81)  评论(0编辑  收藏  举报