0 votes

Comment créer un script avec Automator pour filtrer chaque PDF d'un dossier avec un filigrane différent ?

J'essaie de créer un script pour filtrer un groupe de fichiers PDF dans un dossier, chaque PDF doit avoir un filigrane unique.

Tous les PDF sont dans un dossier, tous les filigranes sont en .png situés dans un autre dossier. J'ai actuellement le filigrane script que j'ai trouvé sur les forums d'Apple, mais celui-ci a été fait pour filtrer tous les fichiers avec un seul filigrane.

Ce dont j'ai besoin, c'est d'un moyen d'ajouter à chaque fichier PDF un filigrane différent (il y a 400 fichiers PDF et 400 filigranes différents).

Automator Screenshot

Voici le contenu du filigrane tool.py :

#!/usr/bin/python
# Watermark each page in a PDF document

import sys #, os
import getopt
import math
from Quartz.CoreGraphics import *
from Quartz.ImageIO import *

def drawWatermark(ctx, image, xOffset, yOffset, angle, scale, opacity):
    if image:
        imageWidth = CGImageGetWidth(image)
        imageHeight = CGImageGetHeight(image)
        imageBox = CGRectMake(0, 0, imageWidth, imageHeight)

        CGContextSaveGState(ctx)
        CGContextSetAlpha(ctx, opacity)
        CGContextTranslateCTM(ctx, xOffset, yOffset)
        CGContextScaleCTM(ctx, scale, scale)
        CGContextTranslateCTM(ctx, imageWidth / 2, imageHeight / 2)
        CGContextRotateCTM(ctx, angle * math.pi / 180)
        CGContextTranslateCTM(ctx, -imageWidth / 2, -imageHeight / 2)
        CGContextDrawImage(ctx, imageBox, image)
        CGContextRestoreGState(ctx)

def createImage(imagePath):
    image = None

    # provider = CGDataProviderCreateWithFilename(imagePath)    # FIXED: replaced by the following CGDataProviderCreateWithURL()
    url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, imagePath, len(imagePath), False)
    provider = CGDataProviderCreateWithURL(url)

    if provider:
        imageSrc = CGImageSourceCreateWithDataProvider(provider, None)
        if imageSrc:
            image = CGImageSourceCreateImageAtIndex(imageSrc, 0, None)
    if not image:
        print "Cannot import the image from file %s" % imagePath
    return image

def watermark(inputFile, watermarkFiles, outputFile, under, xOffset, yOffset, angle, scale, opacity, verbose):

    images = map(createImage, watermarkFiles)

    ctx = CGPDFContextCreateWithURL(CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, outputFile, len(outputFile), False), None, None)
    if ctx:
        pdf = CGPDFDocumentCreateWithURL(CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, inputFile, len(inputFile), False))
        if pdf:

            for i in range(1, CGPDFDocumentGetNumberOfPages(pdf) + 1):
                image = images[i % len(images) - 1]
                page = CGPDFDocumentGetPage(pdf, i)
                if page:
                    mediaBox = CGPDFPageGetBoxRect(page, kCGPDFMediaBox)
                    if CGRectIsEmpty(mediaBox):
                        mediaBox = None

                    CGContextBeginPage(ctx, mediaBox)
                    if under:
                        drawWatermark(ctx, image, xOffset, yOffset, angle, scale, opacity)
                    CGContextDrawPDFPage(ctx, page)
                    if not under:
                        drawWatermark(ctx, image, xOffset, yOffset, angle, scale, opacity)
                    CGContextEndPage(ctx)

        del pdf
        CGPDFContextClose(ctx)
    del ctx

def main(argv):

    verbose = False
    readFilename = None
    writeFilename = None
    under = False
    xOffset = 0.0   # FIXED: changed to float value
    yOffset = 0.0   # FIXED: changed to float value
    angle = 0.0     # FIXED: changed to float value
    scale = 1.0     # FIXED: added
    opacity = 1.0

    # Parse the command line options
    try:
        options, args = getopt.getopt(argv, "vutx:y:a:p:s:i:o:", ["verbose", "under", "over", "xOffset=", "yOffset=", "angle=", "opacity=", "scale=", "input=", "output=", ])
    except getopt.GetoptError:
        usage()
        sys.exit(2)

    for option, arg in options:

        print option, arg

        if option in ("-i", "--input") :
            if verbose:
                print "Reading pages from %s." % (arg)
            readFilename = arg

        elif option in ("-o", "--output") :
            if verbose:
                print "Setting %s as the output." % (arg)
            writeFilename = arg

        elif option in ("-v", "--verbose") :
            print "Verbose mode enabled."
            verbose = True

        elif option in ("-u", "--under"):
            print "watermark under PDF"
            under = True

        elif option in ("-t", "--over"):    # FIXED: changed to "-t" from "t"
            print "watermark over PDF"
            under = False

        elif option in ("-x", "--xOffset"):
            xOffset = float(arg)

        elif option in ("-y", "--yOffset"):
            yOffset = float(arg)

        elif option in ("-a", "--angle"):
            angle = -float(arg)

        elif option in ("-s", "--scale"):
            scale = float(arg)

        elif option in ("-p", "--opacity"):
            opacity = float(arg)

        else:
            print "Unknown argument: %s" % (option)

    if (len(args) > 0):
        watermark(readFilename, args, writeFilename, under, xOffset, yOffset, angle, scale, opacity, verbose);
    else:
        shutil.copyfile(readFilename, writeFilename);

def usage():
    print "Usage: watermark --input <file> --output <file> <watermark files>..."

if __name__ == "__main__":
    print sys.argv
    main(sys.argv[1:])

0 votes

Quelques questions... comment associez-vous le fichier filigrane au fichier PDF ? Avez-vous besoin de filigrane chaque page du PDF ou seulement la première page ? Où le filigrane doit-il être placé ?

0 votes

Chaque PDF ne comporte qu'une seule page, chaque filigrane doit être placé au centre de la page. En général, je peux y parvenir en plaçant les filigranes un par un. Mais faire cela pour 400 fichiers prend un temps considérable. Le problème est que les scripts de filigrane ont été écrits pour utiliser un seul filigrane pour plusieurs fichiers, ou pour un fichier PDF avec plusieurs pages.

0 votes

Les fichiers image du filigrane et les fichiers image correspondants ont-ils le même nom ( par exemple 1.png pour 1.pdf etc.) ?

1voto

user3439894 Points 52496

Je l'ai testé sous MacOS Catalina en utilisant le code de la tool.py dans le PO et le valeur de la options montré pour elle, tout en utilisant PDF documents y les fichiers d'images graphiques pour le filigrane où le fichiers se trouvent à des endroits différents. Cela fonctionne pour moi tel que codé.

Les éléments suivants exemple shell script code suppose que pour chaque PDF document il existe un correspondant fichier d'image graphique du même nom avec un autre extension avec tous les filigranes fichiers être dans un autre répertoire .

Vous devrez définir le valeur de trois variables en haut de l'écran script , p2wf , wext y fqp2pyf tandis que le reste de la valeurs de l'original script sont maintenus sauf s'ils ont déjà été modifiés.

Dans le Automator flux de travail en utilisant un Obtenir les éléments spécifiés de l'explorateur action pour le PDF documents et un Exécuter le Shell script action comme indiqué dans votre OP :

  • Shell : [/bin/bash]
  • Passez l'entrée : [comme arguments]

Remplacer toute code dans le Exécuter le Shell script action par défaut ou non, avec :

    # Path to watermark files.
    # Example: "${HOME}/Pictures/Watermarks"
    # Watermark file extension, e.g.: png
    # Fully qualified pathname to python 'tool.py' file.
    # Example: "${HOME}/bin/tool.py"

p2wf="${HOME}/Pictures/Watermarks"
wext="png"
fqp2pyf="${HOME}/bin/tool.py"

    # f = fully qualified pathname
    # d = directory pathname
    # fn = filename with extension
    # n = filename without extension
    # e = filename extension

for f in "$@"; do

    d="${f%/*}"
    fn="${f##*/}"
    n="${fn%.*}"
    e="${fn##*.}"

    "${fqp2pyf}" \
    --over \
    --xOffset 56 \
    --yOffset 58 \
    --angle 0 \
    --scale 0.11 \
    --opacity 1 \
    --input "${f}" \
    --output "${d}/${n} (COPY).${e}" \
    "${p2wf}/${n}.${wext}"

done  

Nota: Par expérience, je n'utilise jamais ~ pour le répertoire personnel dans scripts . J'utilise par exemple, $HOME o ${HOME} comme ~ peut en fait être problématique dans certaines situations.

0 votes

Merci ! Je vais essayer le code que vous avez suggéré.

0 votes

@Lauro Mota, S'il vous plaît jetez un coup d'oeil à : Que dois-je faire lorsque quelqu'un répond à ma question ?

LesApples.com

LesApples est une communauté de Apple où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres utilisateurs d'appareils Apple, poser vos propres questions ou résoudre celles des autres.

Powered by:

X