首页 > 解决方案 > 将 SVG 节点 (Macaw) 转换为 NSImage Swift4 / Cocoa

问题描述

我正在尝试将 Macaw SVG (Node) 转换为 NSImage。我能够在 Macaw 论坛上找到 IOS 的示例代码,但无法使其在 Cocoa 中运行。

在 Macaw 库中,所有缺少的函数(UIGraphicsBeginImageContext 等)都作为 MGraphicsBeginImageContext 引用,但尚未能够访问它们(使用未解析的标识符“UIGraphicsBeginImageContext”)

这是原始文章中的示例代码https://github.com/exyte/Macaw/pull/382#issuecomment-393422770

func svgToImge(resourceName: String, size: CGSize) -> NSImage {
        if let rootNode = try? SVGParser.parse(path: resourceName)
        {
            let macawView = MacawView(node: rootNode, frame:CGRect(origin: CGPoint.zero, size: size))
            UIGraphicsBeginImageContext(size)
            macawView.layer.render(in: UIGraphicsGetCurrentContext()!)
            let img =  UIGraphicsGetImageFromCurrentImageContext();
            UIGraphicsEndImageContext();
            return img!
        } else {
            return NSImage()
        }
    }

标签: swiftmacossvg

解决方案


这是由 Macaw 的制造商提供的经过调整的代码,似乎可以解决问题。我需要添加一个逆变器,因为图像是颠倒的,他们最初的NSGraphicsContext.current?.graphicsPort建议似乎不稳定/可靠,我最终使用NSGraphicsContext.current?.cgContext代替:

func svgToNSImage(resourcePath: String, size: CGSize) -> NSImage? {

   if let rootNode = try? SVGParser.parse(path: resourcePath) {

        let macawView = MacawView(node: rootNode, frame: CGRect(origin: CGPoint.zero, size: size))
        macawView.wantsLayer = true

        let image = NSImage(size: macawView.bounds.size)
        image.lockFocus()

        //        if let ctx = NSGraphicsContext.current?.graphicsPort {
        if let ctx = NSGraphicsContext.current?.cgContext {
            // image is drawing upside down, invert it and render
            ctx.translateBy(x: 0, y: size.height)
            ctx.scaleBy(x: 1.0, y: -1.0)
            macawView.layer?.render(in: ctx)
        }
        image.unlockFocus()
        return image

    } else { return nil }
}

推荐阅读