2003
01 02 03 04 05 06 07 08 09 10 11 12
2006
01 02 03 04 05 06 07 08 09 10 11 12
2007
01 02 03 04 05 06 07 08 09 10 11 12
2008
01 02 03 04 05 06 07 08 09 10 11 12
2009
01 02 03 04 05 06 07 08 09 10 11 12
2010
01 02 03 04 05 06 07 08 09 10 11 12
2011
01 02 03 04 05 06 07 08 09 10 11 12
2017
01 02 03 04 05 06 07 08 09 10 11 12
2018
01 02 03 04 05 06 07 08 09 10 11 12
 
Jun
27
2007

How to draw on PDF?

用 Cocoa 的人可以輕鬆地透過 [NSView dataWithPDFInsideRect] 產生 PDF(詳見 Cocoa Dev Central: Create A PDF)。但如果你想在已經有的 PDF 上面加一些東西,例如浮水印或者簽名,你會發覺用 NSImage 叫進來畫的 PDF 都會畫成點陣圖。而 PDFKit 在這方面除了加 annotation 以外完全幫不上忙。

Cocoa Developers found that it’s easy to generate PDF files from the scratch with [NSView dataWithPDFInsideRect]. But what if you just want to add something (like watermark, signature, etc.) on an existing PDF file? NSImage will render the vector based PDF into bitmap representation and PDFKit do nothing help other than adding annotation.

這時,你只能用 Quartz 提供的功能了。在 ApplicationServices.framework 底下,應該可以找到屬於 CoreGraphics ,以 CGPDF 開頭的 API 們。

You can use Quartz framework to achieve this task. There are APIs starting with CFPDF* under ApplicationServices umbrella framework that can help you.

你可以這樣做:

 // Where to save the result PDF 
 CGContextRef context = CGPDFContextCreateWithURL(...); 
 // Go lookup docs! 
 // Where is the original PDF 
 CGPDFDocumentRef originalPDF = CGPDFDocumentCreateWithURL(...); 
 // Loop through each pages, starting from 1 
 for (p = 1; p < = CGPDFDocumentGetNumberOfPages(originalPDF); p++) { 
   CGRect rect = CGPDFDocumentGetMediaBox(originalPDF, p); 
   CGContextBeginPage(context, &rect);
   CGContextSaveGState(context);
   CGContextClipToRect(context, rect);
   CGContextDrawPDFDocument(context, rect, originalPDF, p);
   /* Draw anything you like here using CGContextDraw/Paint/Fill* */
   CGContextRestoreGState(context);
   CGContextEndPage(context); 
} // Save the result PDF CGContextRelease(context); 

警告,按照目前 OSX 的公開文件,不管你改變了多麼微小的部份,只能重新產生整個 PDF 。而這個部份 Apple 的記憶體管理沒有寫得很好,產生一個 200MB 的 PDF 竟然花掉我近 700MB 的虛擬記憶體!(實體記憶體吃掉接近 300MB)因此大型的 PDF 最好先用 iText 之類的 PDF library 拆開,畫好再重新組合起來。

WARNING: According to the documents from Apple, no matter how slightly you modify, you have to save the whole content into an entirely new PDF file. This method devour about 700MB virtual memory (and 300MB physical ram) when I just want to add a tiny logo on a 200MB PDF file. Hence, if you have to add tiny things on a large PDF file, split them using library like iText first, use the above method on each page and join them together. 否則,你也可以自己去看 PDF specification ,我花了兩天大概讀了四百頁就讀不下去了…

 
 

Write Concisely