2017-06-19 46 views
0

我的目標是在PDF上編寫文本,如註釋。在macOS上使用Swift在PDF上繪圖

我實現了它將PDFPage轉換爲NSImage,我畫了NSImage,然後保存了圖像形成的PDF。

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) 

的問題顯然是out(輸出PDF的新頁面)是圖像的PDFPage不是常規的。因此,輸出PDF的大小非常大,您無法複製和粘貼任何內容。這只是一系列圖像。

我的問題是,如果有一種方法可以在不使用NSImage的情況下以編程方式在PDF頁面上添加簡單文本。任何想法?

注意:這個類的iOS編程UIGraphicsBeginPDFPageWithInfo這可能是非常有用的在我的情況。但是我找不到macOS開發的類似類。

+0

耶...你可以使用html來做到這一點。 –

+0

@ClaudioCastro沒有其他辦法?以下是如何解決我在iOS上的問題,但我無法在macOS中找到同樣的方法:https://stackoverflow.com/questions/32113468/how-to-draw-text-in-pdf-context-in-swift – Matt

+0

我很抱歉,您談論macOS ...我的解決方案是用於iOS的,我使用html生成帶有文本和圖片的pdf。 –

回答

3

您可以在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() 
+0

完美答案!我現在知道了。 – Matt

+0

嘿,搶!如果我需要使用新繪製的頁面怎麼辦?使用您的代碼,新頁面會保存在** outUrl **路徑中,但無法以編程方式訪問它。我唯一能做的就是將PDFPage保存爲** outUrl **,然後再次打開。 我看了一下CGContext的文檔頁面,但是我沒有找到任何可以獲得修改過的PDFPage的東西。任何想法如何在** gc.closePDF()**調用後立即獲取它?這並不重要,實際上只是爲了好奇。 – Matt

+1

使用帶'CGDataConsumer'參數的'CGContext'初始值設定項。在'closePDF'後,您可以從數據中創建一個新的'PDFDocument'實例,而不必通過文件。 –