Aide-mémoire: Modification de pdfs en ligne de commande

  cli pdf qpdf poppler pdftk shell terminal

Table des matières

Outils, sources et installation

Sources pour ce document :

https://qpdf.readthedocs.io/ https://github.com/qpdf/qpdf

Prérequis : pdftk-java (pdftk), ghostscript (gs), poppler (pdfinfo, pdftotext, pdfseparate, pdfunite…), qpdf.

ℹ️ pdftk original n'est plus maintenu depuis 2013. Son remplaçant pdftk-java propose la même interface en ligne de commande. Beaucoup de ces opérations sont également réalisables avec poppler-utils, sans dépendance Java.

installation des outils :

brew install qpdf poppler

Inspection d'un pdf

Informations en général:

# Avec poppler :
pdfinfo document.pdf

# Nombre de pages, un peu inutile mais pour l'exemple :
pdfinfo document.pdf | grep Pages
# ou avec qpdf
qpdf --show-npages document.pdf

Diagnostic

qpdf --check document.pdf

Polices utilisées :

# Avec poppler
pdffonts document.pdf

Extraire le texte brut d'un PDF

# avec poppler — sortie sur stdout
pdftotext document.pdf -
# pages 2 à 5 : 
pdftotext -f 2 -l 5 document.pdf -

# avec poppler —vers un fichier
pdftotext document.pdf document.txt

# avec poppler — conserver la mise en page (colonnes, espacements)
pdftotext -layout document.pdf document.txt

Extraire les images embarquées dans un PDF

# avec poppler
pdfimages -all document.pdf images/img

Chiffrement, xref, objets, structure JSON

qpdf --show-encryption document.pdf
qpdf --show-xref document.pdf
qpdf --show-object=10 document.pdf
# stream décodé / brut d'un objet :
qpdf --show-object=10 --filtered-stream-data document.pdf
qpdf --show-object=10 --raw-stream-data document.pdf

# export/import JSON complet (pour modifs programmatiques : recadrage, métadonnées...)
qpdf --json-output input.pdf > structure.json
qpdf --json-input structure.json output.pdf

Recadrage

cropbox cropping

Le contenu n'est pas effacé, il est juste caché

mediabox cropping

Mettons que la media box soit de 0 0 612 792 (obtenu avec pdfinfo par exemple). On peut alors faire :

qpdf in.pdf --pages . -- --mediabox "100 100 500 700" out.pdf
qpdf out.pdf --pages . -- --mediabox "0 0 612 792" recovered.pdf

La restauration n'est possible que si aucun autre logiciel n'a réécrit le PDF entre-temps.

pdfcrop avec les marges

plus simple : pdfcrop input.pdf cropped.pdf

Autres boxes : TrimBox (format final après coupe), BleedBox (fond perdu), ArtBox (zone de contenu utile) — toujours contenues dans la MediaBox.

Recadrage via JSON (scriptable, en masse)

qpdf --json-output input.pdf |
  jq '(.objects[] | select(has("/MediaBox")) | ."/CropBox") = [50, 50, 562, 742]' > temp.json
qpdf --json-input temp.json output.pdf

Recadrage via QDF (édition manuelle)

qpdf --qdf --object-streams=disable original.pdf editable.pdf
# éditer les /CropBox dans editable.pdf, puis réécrire proprement :
qpdf editable.pdf output.pdf

Manipulation des pages

Diviser un PDF en fichiers d'une page chacun

# avec pdftk-java
pdftk input.pdf burst output page_%03d.pdf

# avec poppler
pdfseparate input.pdf page_%03d.pdf

# avec qpdf (un fichier par page, ou groupé avec =n)
qpdf --split-pages input.pdf %d_page.pdf
qpdf --split-pages=2 input.pdf sortie.pdf

Fusionner plusieurs PDFs en un seul

Fusion de tous les pdfs du dossier :

# avec pdftk-java
pdftk *.pdf cat output merged.pdf

# avec poppler
pdfunite *.pdf merged.pdf

Fusion avec ordre explicite:

pdfunite cover.pdf chapter*.pdf appendix.pdf book.pdf

Avec qpdf, en conservant les métadonnées du fichier principal :

qpdf main.pdf --pages main.pdf 1-z annexes.pdf 1-z -- combine.pdf

Fusion alternée (entrelacement, utile pour un recto/verso scanné séparément) :

qpdf --collate --empty --pages odd.pdf even.pdf -- assembled.pdf
# ou --collate=2,1 pour 2 pages du premier, 1 du second, etc.

Extraire des pages d'un pdf :

# == avec pdftk-java :
pdftk original.pdf cat 3-7 output extrait.pdf

# == avec qpdf :
qpdf original.pdf --pages original.pdf 3-7 -- extrait.pdf

# == avec poppler :
pdfseparate -f 3 -l 7 original.pdf page-%d.pdf
pdfunite page-{3,4,5,6,7}.pdf extrait.pdf
# ou 
pdfunite $(printf "page-%d.pdf " {3..7}) extrait.pdf
# puis
rm page-{2..7}.pdf

Syntaxe de sélection qpdf : N (page N), N-M (plage, 7-3 = ordre décroissant), z (dernière page), rN (N-ième depuis la fin), 1,3,5-7 (liste), 1-10,x5-6 (exclusion), 1-10:even/:odd (parité).

# extrait sans métadonnées/signets du document d'origine
qpdf --empty --pages original.pdf 1-10 -- pages_seules.pdf

Supprimer des pages:

# avec poppler:
qpdf input.pdf --pages . 1-4,8-z -- output.pdf
# ou avec pdftk:
pdftk input.pdf cat 1-4 8-end output output.pdf

Réorganiser des pages

pdftk input.pdf cat 5 1 2 3 4 output reordered.pdf
# ou:
qpdf input.pdf --pages . 5,1-4 -- reordered.pdf

Faire pivoter des pages

# toutes les pages, rotation relative (+/-) : pas besoin de connaître l'orientation actuelle
qpdf --rotate=+90 input.pdf output.pdf

# une page précise (page 5)
qpdf input.pdf output.pdf --rotate=+90:5

# remettre à l'endroit
qpdf input.pdf output.pdf --rotate=0

Conversion de pdf (svg, png, html)

Pdf to svg

# Avec inkscape :
inkscape myfile.pdf --export-type=svg

# Avec poppler
pdftocairo -svg myfile.pdf myfile.svg
# Pour traiter tout un dossier:
for f in \*.pdf; do
pdftocairo -svg "$f" "${f%.pdf}.svg"
done

Pdf to png

pdftocairo -png -r 150 file.pdf frame produit frame-01.png, frame-02.pbg etc, une image par page. Mettre une résolution 300 pour impression

Remarque : on peut lui dire de ne prendre que la cropbox, car pdftocairo prend tout par défaut:

pdftocairo -png -cropbox input.pdf output sinon il faut cropper avant avec une autre méthode

en niveaux de gris et 100ppp: pdftocairo -png -gray -r 100 file.pdf page

Convertir un PDF en HTML (avec mise en forme)

# avec poppler
pdftohtml document.pdf

Sécurité

Protéger un PDF par mot de passe

qpdf --encrypt MonMotDePasse MonMotDePasseOwner 256 -- input.pdf output.pdf

Premier mot de passe = utilisateur (ouverture), second = propriétaire (permissions). Longueur de clé : 40, 128 ou 256 bits.

Restreindre les permissions (impression, modification) :

qpdf document.pdf document_secure.pdf --encrypt lecture modif 128 --print=none --modify=none --

Autres options : --extract=y|n, --annotate=y|n. Chiffrement faible (40/128 RC4) : --allow-weak-crypto. Owner vide en 256 bits : --allow-insecure.

Supprimer le mot de passe d'un PDF

qpdf --password=MonMotDePasse --decrypt input.pdf output.pdf

Linéarisation (Fast Web View)

Réorganise le PDF pour afficher la 1ère page avant téléchargement complet (streaming web).

qpdf input.pdf output.pdf --linearize
qpdf --check-linearization output.pdf

Métadonnées

# anonymiser (dictionnaire Info + flux XMP)
qpdf original.pdf --remove-info --remove-metadata sans_meta.pdf

Lors d'une fusion avec --pages, les métadonnées conservées sont celles du fichier principal (premier argument).

Modification fine (titre, auteur…) via JSON :

qpdf --json-output doc.pdf > temp.json
# éditer "/Info" : "/Title", "/Author" (préfixer les valeurs par "u:")
qpdf --json-input temp.json doc_modifie.pdf

Réparation de PDF corrompus

# réécriture simple : reconstruit la table xref
qpdf fichier_endommage.pdf fichier_repare.pdf

# vérifier puis réparer
qpdf --check fichier_endommage.pdf output.pdf

Cas limites : qpdf --stream-data=uncompress --qdf in.pdf editable.pdf puis édition manuelle et réécriture.

Autres

OCR

ocrmypdf input.pdf output.pdf
# ou 
ocrmypdf --language fra input.pdf output.pdf

Ajouter un fond de page (tampon) à un PDF

pdftk input.pdf stamp tampon.pdf output output.pdf

Compresser un PDF avec Ghostscript

gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/ebook -dNOPAUSE -dQUIET -dBATCH -sOutputFile=output.pdf input.pdf

Niveaux de compression : /screen (72dpi) < /ebook (150dpi) < /printer (300dpi) < /prepress

Décompresser un pdf

qpdf --qdf --object-streams=disable input.pdf output.pdf

Pratique pour faire des diffs Git, voir la structure interne etc.