在macOS上使用Swift绘制PDF

时间:2017-06-19 21:11:05

标签: swift macos pdf

我的目标是在PDF上写文字,就像注释一样。

我实现了将PDFPage转换为NSImage,我绘制了NSImage,然后保存了由图像形成的PDF。

>>> bc = dis.Bytecode(lambda something: something.x > something.y)
>>> for instr in bc:
...     if instr.opname == "LOAD_ATTR":
...         print(instr.argval)
...
x
y
>>>

问题显然是let image = NSImage(size: pageImage.size) image.lockFocus() let rect: NSRect = NSRect(x: 50, y: 50, width: 60, height: 20) "Write it on the page!".draw(in: rect, withAttributes: someAttributes) image.unlockFocus() let out = PDFPage(image: image) (输出PDF的新页面)是图像的PDF页面而不是常规页面。因此输出PDF的大小非常大,您无法在其上复制和粘贴任何内容。它只是一系列图像。

我的问题是,是否可以在不使用NSImage的情况下以编程方式在PDF页面上添加简单文本。有什么想法吗?

注意:在iOS编程out中有这个类,这对我的情况非常有帮助。但我无法找到类似的macOS开发类。

1 个答案:

答案 0 :(得分:6)

您可以在macOS上创建PDF图形上下文并在其中绘制PDFPage。然后,您可以使用Core Graphics或AppKit图形将更多对象绘制到上下文中。

这是我通过打印您的问题创建的测试PDF: input PDF

这是将该页面绘制到PDF上下文中,然后在其上绘制更多文本的结果:

output PDF

这是我编写的将第一个PDF转换为第二个PDF的代码:

import Cocoa
import Quartz

let inUrl: URL = URL(fileURLWithPath: "/Users/mayoff/Desktop/test.pdf")
let outUrl: CFURL = URL(fileURLWithPath: "/Users/mayoff/Desktop/testout.pdf") as CFURL

let doc: PDFDocument = PDFDocument(url: inUrl)!
let page: PDFPage = doc.page(at: 0)!
var mediaBox: CGRect = page.bounds(for: .mediaBox)

let gc = CGContext(outUrl, mediaBox: &mediaBox, nil)!
let nsgc = NSGraphicsContext(cgContext: gc, flipped: false)
NSGraphicsContext.current = nsgc
gc.beginPDFPage(nil); do {
    page.draw(with: .mediaBox, to: gc)

    let style = NSMutableParagraphStyle()
    style.alignment = .center

    let richText = NSAttributedString(string: "Hello, world!", attributes: [
        NSFontAttributeName: NSFont.systemFont(ofSize: 64),
        NSForegroundColorAttributeName: NSColor.red,
        NSParagraphStyleAttributeName: style
        ])

    let richTextBounds = richText.size()
    let point = CGPoint(x: mediaBox.midX - richTextBounds.width / 2, y: mediaBox.midY - richTextBounds.height / 2)
    gc.saveGState(); do {
        gc.translateBy(x: point.x, y: point.y)
        gc.rotate(by: .pi / 5)
        richText.draw(at: .zero)
    }; gc.restoreGState()

}; gc.endPDFPage()
NSGraphicsContext.current = nil
gc.closePDF()