Draw on a PDF using Swift on macOS

前端 未结 1 1499
忘掉有多难
忘掉有多难 2021-02-11 08:42

My goal is to write text on a PDF, like an annotation.

I achieved it transforming the PDFPage to a NSImage, I drew on the NSImage then I saved the PDF formed by the imag

1条回答
  •  别那么骄傲
    2021-02-11 09:34

    You can create a PDF graphics context on macOS and draw a PDFPage into it. Then you can draw more objects into the context using either Core Graphics or AppKit graphics.

    Here's a test PDF I created by printing your question:

    And here's the result from drawing that page into a PDF context, then drawing more text on top of it:

    Here's the code I wrote to transform the first PDF into the second 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()
    

    0 讨论(0)
提交回复
热议问题