[使用Mac OS X API,我正在尝试应用Quartz过滤器来保存PDF文件,就像可以从“预览”应用程序中的“另存为”对话框中进行保存一样。到目前为止,我已经编写了以下代码(使用Python和pyObjC,但这对我来说并不重要):
-filter-pdf.py:开始
from Foundation import *
from Quartz import *
import objc
page_rect = CGRectMake (0, 0, 612, 792)
fdict = NSDictionary.dictionaryWithContentsOfFile_("/System/Library/Filters/Blue
\ Tone.qfilter")
in_pdf = CGPDFDocumentCreateWithProvider(CGDataProviderCreateWithFilename ("test
.pdf"))
url = CFURLCreateWithFileSystemPath(None, "test_out.pdf", kCFURLPOSIXPathStyle,
False)
c = CGPDFContextCreateWithURL(url, page_rect, fdict)
np = CGPDFDocumentGetNumberOfPages(in_pdf)
for ip in range (1, np+1):
page = CGPDFDocumentGetPage(in_pdf, ip)
r = CGPDFPageGetBoxRect(page, kCGPDFMediaBox)
CGContextBeginPage(c, r)
CGContextDrawPDFPage(c, page)
CGContextEndPage(c)
-filter-pdf.py:结束
不幸的是,未应用过滤器“ Blue Tone”,输出PDF看起来与输入PDF完全一样。
问题:我错过了什么?如何应用过滤器?
嗯,文档并不保证创建和使用“ fdict”的这种方式应会导致应用过滤器。但是我只是重写了(就我所能做到的)示例代码/Developer/Examples/Quartz/Python/filter-pdf.py,它随Mac的旧版本一起分发(与此同时,此代码也无法使用):
----- filter-pdf-old.py:开始
from CoreGraphics import *
import sys, os, math, getopt, string
def usage ():
print '''
usage: python filter-pdf.py FILTER INPUT-PDF OUTPUT-PDF
Apply a ColorSync Filter to a PDF document.
'''
def main ():
page_rect = CGRectMake (0, 0, 612, 792)
try:
opts,args = getopt.getopt (sys.argv[1:], '', [])
except getopt.GetoptError:
usage ()
sys.exit (1)
if len (args) != 3:
usage ()
sys.exit (1)
filter = CGContextFilterCreateDictionary (args[0])
if not filter:
print 'Unable to create context filter'
sys.exit (1)
pdf = CGPDFDocumentCreateWithProvider (CGDataProviderCreateWithFilename (args[1]))
if not pdf:
print 'Unable to open input file'
sys.exit (1)
c = CGPDFContextCreateWithFilename (args[2], page_rect, filter)
if not c:
print 'Unable to create output context'
sys.exit (1)
for p in range (1, pdf.getNumberOfPages () + 1):
#r = pdf.getMediaBox (p)
r = pdf.getPage(p).getBoxRect(p)
c.beginPage (r)
c.drawPDFDocument (r, pdf, p)
c.endPage ()
c.finish ()
if __name__ == '__main__':
main ()
----- filter-pdf-old.py:结束
================================================ =======================
基于答案的工作代码:
from Foundation import *
from Quartz import *
pdf_url = NSURL.fileURLWithPath_("test.pdf")
pdf_doc = PDFDocument.alloc().initWithURL_(pdf_url)
furl = NSURL.fileURLWithPath_("/System/Library/Filters/Blue Tone.qfilter")
fobj = QuartzFilter.quartzFilterWithURL_(furl)
fdict = { 'QuartzFilter': fobj }
pdf_doc.writeToFile_withOptions_("test_out.pdf", fdict)
两种方法-如果需要打开和修改现有文件,请使用PDFKit的PDFDocument(reference)并使用PDFDocument的writeToFile_withOptions_以及选项dict,其中包括所需过滤器的“ QuartzFilter”选项。
OTOH,如果您需要自己的图形并准备好CGContext,可以按照以下方式使用:
from Quartz import *
data = NSMutableData.dataWithCapacity_(1024**2)
dataConsumer = CGDataConsumerCreateWithCFData(data)
context = CGPDFContextCreate(dataConsumer, None, None)
f = QuartzFilter.quartzFilterWithURL_(NSURL.fileURLWithPath_("YourFltr.qfilter"))
f.applyToContext_(context)
# do your drawing
CGPDFContextClose(context)
# the PDF is in the data variable. Do whatever you need to do with the data (save to file...).