Примените Кварцевый фильтр при сохранении PDF в Mac OS X 10.6.3 - PullRequest
2 голосов
/ 28 апреля 2010

Используя Mac OS X API, я пытаюсь сохранить файл PDF с примененным кварцевым фильтром, как это возможно в диалоговом окне «Сохранить как» в приложении «Просмотр». До сих пор я написал следующий код (используя Python и pyObjC, но для меня это не важно):

- 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: конец

К сожалению, фильтр «Голубой тон» не применяется, выходной PDF выглядит точно так же, как входной PDF.

Вопрос: что я пропустил? Как применить фильтр?

Что ж, документация не обещает, что такой способ создания и использования "fdict" должен привести к тому, что фильтр будет применен. Но я просто переписал (насколько я могу) пример кода /Developer/Examples/Quartz/Python/filter-pdf.py, который распространялся с более старыми версиями Mac (тем временем этот код тоже не работает):

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

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

Рабочий код, основанный на ответе:

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 Ответ

4 голосов
/ 29 апреля 2010

два подхода - если вам нужно открыть и изменить уже существующий файл, используйте PDFDocument PDFKit ( ссылка ) и используйте writeToFile_withOptions_ в PDFDocument с опцией 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...).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...