1

How to create a PDF document from a batch of images ?

===

Belowis what I tried before posting this question:

The ImageMagick way, but the PDF document generated is too big:

convert *.ppm book.pdf

The Preview tool way, the created document is much smaller but it creates margins.

The sips way, not working for some reason:

sips -s format pdf *.ppm --out 'book.pdf' 1>/dev/null 2>&1

There also img2pdf which looks good but I couldn't install it on mac (it's not in brew's list of packages).

1 Answers1

3

Apple's own Automator action uses a python script to access Core Graphics. It works, but it's slow. Here's a better python script which uses Apple's newer PDFKit framework.

You can use this from the Terminal with filenames as arguments, or you can stick it in an Automator Run Shell Script Action.

No installations or dependencies.

#!/usr/bin/python
# coding: utf-8
#
# IMAGE2PDF v.2.0 : Convert image files to one PDF.
# by Ben Byram-Wigfield 

import sys, os
import Quartz as Quartz
from LaunchServices import kUTTypePDF
from CoreFoundation import NSImage

def getFilename(filepath, basename):
    fullname = basename + ".pdf"
    i=0
    while os.path.exists(os.path.join(filepath, fullname)):
        i += 1
        fullname = basename + " %02d.pdf"%i
    return os.path.join(filepath, fullname)

def imageToPdf(argv):
    prefix = os.path.dirname(argv[0]) 
    filename = "Combined"
    pdfout = getFilename(prefix, filename)

    for index, eachFile in enumerate(argv):
        image = NSImage.alloc().initWithContentsOfFile_(eachFile)
        if image:
            page = Quartz.PDFPage.alloc().initWithImage_(image)
            if index == 0:
                pageData = page.dataRepresentation()
                pdf = Quartz.PDFDocument.alloc().initWithData_(pageData)
            else:
                pdf.insertPage_atIndex_(page, index)

    pdf.writeToFile_(pdfout)

if __name__ == "__main__":
    imageToPdf(sys.argv[1:])
benwiggy
  • 35,635