Apply a Quartz filter while saving PDF under Mac OS X 10.6.3

本小妞迷上赌 提交于 2019-12-13 17:06:46

问题


Using Mac OS X API, I'm trying to save a PDF file with a Quartz filter applied, just like it is possible from the "Save As" dialog in the Preview application. So far I've written the following code (using Python and pyObjC, but it isn't important for me):

-- filter-pdf.py: begin

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: end

Unfortunalte, the filter "Blue Tone" isn't applied, the output PDF looks exactly as the input PDF.

Question: what I missed? How to apply a filter?

Well, the documentation doesn't promise that such way of creating and using "fdict" should cause that the filter is applied. But I just rewritten (as far as I can) sample code /Developer/Examples/Quartz/Python/filter-pdf.py, which was distributed with older versions of Mac (meanwhile, this code doesn't work too):

----- filter-pdf-old.py: begin

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: end

=======================================================================

The working code based on the answer:

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)

回答1:


two approaches - if you need to open and modify an already existing file, use the PDFKit's PDFDocument (reference) and use PDFDocument's writeToFile_withOptions_ with option dict including the "QuartzFilter" option of needed filter.

OTOH if you need your own drawing and have a CGContext at hand, you can use something along these lines:

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...).


来源:https://stackoverflow.com/questions/2728778/apply-a-quartz-filter-while-saving-pdf-under-mac-os-x-10-6-3

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!