convertir des images en pdf: Comment créer des pages PDF de même taille

45

J'ai fait quelque chose comme

convert -page A4 -compress A4 *.png CH00.pdf

Mais la 1ère page est beaucoup plus grande que les pages suivantes. Cela se produit même si les dimensions de l’image sont similaires. Ces images sont numérisées et recadrées, ce qui peut présenter de légères différences de dimensions.

Je pensais que -page A4devrait fixer la taille des pages?

Jiew Meng
la source

Réponses:

60

La dernière fois que j'ai utilisé convertpour une telle tâche, j'ai explicitement spécifié la taille de la destination via le redimensionnement:

$ i=150; convert a.png b.png -compress jpeg -quality 70 \
      -density ${i}x${i} -units PixelsPerInch \
      -resize $((i*827/100))x$((i*1169/100)) \
      -repage $((i*827/100))x$((i*1169/100)) multipage.pdf

La convertcommande n'utilise pas toujours le DPI en tant qu'unité de densité / format de page par défaut; nous spécifions donc explicitement le DPI avec l' -unitsoption (sinon, vous obtiendrez des résultats différents avec des combinaisons de versions / formats d'entrée différentes). Le nouveau format (spécifié via -resize) correspond à la dimension d'une page DIN A4 en pixels. L'argument resize spécifie la taille maximale de la page. La résolution et la qualité à choisir dépendent exactement du cas d'utilisation. J'ai sélectionné 150 ppp et une qualité moyenne pour gagner de la place alors qu'elle n'a pas l'air trop mauvaise lorsqu'elle est imprimée sur du papier.

Notez que convertpar défaut, le rapport de format ne change pas avec l'opération de redimensionnement:

Redimensionner adaptera l'image à la taille demandée. Il ne remplit pas, la taille de la boîte demandée.

( Manuel ImageMagick )

Selon la version d'ImageMagick et les formats d'entrée concernés, il peut être correct d'omettre l' -repageoption. Mais parfois, cela est nécessaire et sans cette option, l'en-tête PDF pourrait contenir des dimensions trop petites. En tout cas, -repageça ne devrait pas faire mal.

Les calculs utilisent une arithmétique entière car bashne la supporte que. Avec zshles expressions peuvent être simplifiées - ie remplacées par $((i*8.27))x$((i*11.69)).

Images Lineart

Si les fichiers PNG sont des images à deux niveaux (noir et blanc, aka lineart), l' img2pdfoutil produit des résultats supérieurs à ImageMagick convert. Cela signifie que img2pdfc'est plus rapide et que les PDF sont plus petits.

Exemple:

$ img2pdf -o multipage.pdf a.png b.png

ou:

$ img2pdf --pagesize A4 -o multipage.pdf a.png b.png
maxschlepzig
la source
2
lors de l'utilisation, -repage a4je reçois uninvalid argument for option '-repage': a4
Scolytus
1
@Scolytus, sur un système Fedora 19, j'ai observé un problème similaire - il semble que -repagele nom a4 ne soit plus supporté. J'ai travaillé autour de cela via l'arithmétique shell:-repage $((150*8.27))x$((150*11.69))
maxschlepzig
Je suppose que ces nombres magiques sont 150 dpi et A4 exprimés en unités héritées?
Michael Scheper
@ MichaelScheper, oui, dpi et pouces.
maxschlepzig
Merci aide moi. En fait, l' -density 150argument était important d'ajouter.
dma_k
23

Ce que vous voulez vraiment utiliser, c'est:

$ convert a.png b.png -compress jpeg -resize 1240x1753 \
                      -extent 1240x1753 -gravity center \
                      -units PixelsPerInch -density 150x150 multipage.pdf

-extentétend réellement l'image à 1240x1753, tout en conservant -resizele rapport de l'image, en l'ajustant dans un 1240x...ou ...x1753.

Le -gravityparamètre est facultatif mais peut être utilisé pour centrer l'image lors de l'extension.

Caugner
la source
1
Je vous remercie! -extentest vraiment ce que je veux utiliser :) - s'il vous plaît, ajoutez la citation manquante à gauche devant -extent, merci!
Brownian
Merci, j'ai finalement ajouté la tique manquante! ;-)
caugner
9

Ajout à la réponse de Caugner :

après avoir installé IM v6.6.9-7, j’ai découvert que le -gravityparamètre devait être placé entre les deux -resizeet -extentavoir un effet.

de plus (bien que cela ne fasse pas partie de la question op), j’ai trouvé la possibilité d’attirer une couleur de fond différente, ce qui donnerait la maîtrise totale de

convert in.jpg -resize 1240x1750 -background black -compose Copy\
               -gravity center -extent 1240x1750\
               -units PixelsPerInch -density 150 out.pdf

Une autre variation utile que j'utilise souvent lorsque je ne veux pas redimensionner une image qui vient déjà dans le bon rapport d'aspect, tout en conservant sa résolution individuelle.

convert in.jpg -units PixelsPerInch -set density '%[fx:w/8.27]'\
               -repage a4 out.pdf

où la densité cible est déterminée dynamiquement en calculant la largeur divisée par 8.27 (qui est la largeur en pouces d'une page A4). le -repage a4paramètre peut être omis la plupart du temps, mais j'ai eu quelques cas où le .pdf résultant aurait un format différent légèrement différent des dimensions A4 de 210x297mm (8.27x11.6 ")

antiplexe
la source
2

J'ai trouvé le code de Mikher très utile, mais le PDF est entièrement présenté sous la forme Portrait ou Paysage, je l'ai donc modifié pour vérifier la mise en page de chaque fichier d'entrée et la faire correspondre à la sortie.

Je n'ai pas inclus l'édition de Yotam car cela fonctionne sans cela sur ma boîte Ubuntu 15.04.

$#!/bin/bash

# Resizes files to A4 (or other size - change PaperWdthMetr and PaperHghtMetr below) and merges into a PDF

export LOCALE=C

[[ "${2}x" == "x" ]] && \
 { echo "Usage: $( basename $0 ) output.pdf extension"
   echo "       merges all files (*.extension) into a single PDF"
   echo "If files z_merged.pdf, z_temp.pdf or $1 exist, they will be overwritten"
 exit 1
 } || \
 OutName="$1"
 ext="$2"

# Set basic variables
unset Debug #; Debug="yes" # print extra messages
IMBackground="white"      # what colour for paper
IMQuality="91"            # JPEG compression level
PaperHghtMetr="297"       # milimeters, 297 for ISO A4
PaperWdthMetr="210"       # milimeters, 210 for ISO A4
PaperDens="200"           # maximum (wanted) dpi for a page
PaperHInch=$( echo scale=5\; $PaperHghtMetr / 2.54 / 10      | bc -l ) # Inch
PaperWInch=$( echo scale=5\; $PaperWdthMetr / 2.54 / 10      | bc -l ) # Inch
PaperRtio=$(     echo scale=5\; $PaperWdthMetr / $PaperHghtMetr | bc -l )

# Remove temporary files from prior run
rm -rf z_merged.pdf z_temp.pdf 2>/dev/null

# Process any $ext file in the current directory
find . -maxdepth 1 -name "*.${ext}" -print0 | sort -z | while read -d '' -r FName
do
  echo "Converting $FName"
  ImgIdentify=$( identify -format "%w %h" "$FName" )
  ImgWdthOrig=$( echo $ImgIdentify | cut -d" " -f1  )
  ImgHghtOrig=$( echo $ImgIdentify | cut -d" " -f2  )
  ImgRtio=$( echo "scale=5; $ImgWdthOrig / $ImgHghtOrig"  | bc -l )


# Match output page layout - Landscape or Portrait - to input file
  if (( $(echo "$ImgRtio > 1 && $PaperRtio > 1 || $ImgRtio < 1 && $PaperRtio < 1" |bc -l) )); then
    echo "Portrait"
    PaperHghtInch=$PaperHInch
    PaperWdthInch=$PaperWInch
  else
    echo "Landscape"
    PaperHghtInch=$PaperWInch
    PaperWdthInch=$PaperHInch
  fi


  [[ $( echo $ImgRtio'>'$PaperRtio | bc -l ) == 1 ]] \
    && ImgDens=$( echo scale=0\; $ImgWdthOrig / $PaperWdthInch | bc -l ) \
    || ImgDens=$( echo scale=0\; $ImgHghtOrig / $PaperHghtInch | bc -l )
  [[ $Debug ]] && echo "ImgDens1: $ImgDens"
  [[ $( echo $ImgDens'>'$PaperDens | bc -l ) == 1 ]] \
    && ImgDens=$PaperDens
  [[ $Debug ]] && echo "ImgDens2: $ImgDens"

  ImgWdth=$( echo $PaperWdthInch \* $ImgDens | bc -l ) # pixels
  ImgHght=$( echo $PaperHghtInch \* $ImgDens | bc -l ) # pixels

  [[ $Debug ]] && echo "ImgWdth: $ImgWdth".
  [[ $Debug ]] && echo "ImgHght: $ImgHght".

  convert "${FName}"                                 \
          -resize ${ImgWdth}x${ImgHght}              \
          -background $IMBackground -gravity center  \
          -extent ${ImgWdth}x${ImgHght}              \
          -units PixelsPerInch -set density $ImgDens \
          -repage ${ImgWdth}x${ImgHght}+0+0          \
          -compress JPEG                             \
          -quality $IMQuality                        \
          "${FName%.$ext}.pdf"

  # Merge new PDF page with prior pages
  [[ -f z_merged.pdf ]] && \
   { pdftk z_merged.pdf "${FName%.$ext}.pdf" cat output z_temp.pdf
     mv z_temp.pdf z_merged.pdf
   } || \
     cp "${FName%.$ext}.pdf" z_merged.pdf
  [[ $Debug ]] || rm -rf "${FName%.$ext}.pdf"
done

[[ -f z_merged.pdf ]] && mv z_merged.pdf "$OutName"
echo "Done."
utilisateur173283
la source
2

Je trouve le script suivant pratique, qui combine les réponses énumérées ici ainsi que certains problèmes rencontrés avec le calcul en virgule flottante:

endInputArgs=$(($#-1))

quoted_args="$(printf " %q" "${@:1:$endInputArgs}")"
output_arg="$(printf " %q" "${@:$#:1}")"

ratiox=$(echo "150*8.27" | bc -l)
ratioy=$(echo "150*11.69" | bc -l)

bash -c "convert $quoted_args -compress jpeg -resize 1240x1753 \
  -units PixelsPerInch -density 150x150 -repage ${ratiox}x${ratioy} $output_arg"

Le script est appelé (enregistré dans un fichier images2pdf)

images2pdf file\ 1.jpg file\ 2.jpg file\ 3.jpg output.pdf

/ edit: Ajout du drapeau "-l" selon le commentaire de tanius pour une meilleure précision.

RindPHI
la source
Astuce générale: $(echo "150*8.27" | bc)n'est pas encore génial pour la virgule flottante. Fonctionne ici car c'est une multiplication. Pour $(echo "150/8.27" | bc)cependant, le résultat est 18(tronqué à nombre entier). Au lieu de cela, appelez bcavec plus haut scale:, $(echo "150/8.27" | bc -l)le résultat est 18.137847….
tanius
1

Je me débattais aussi avec ça. Sur la base des informations ci-dessus, j'ai écrit un script qui ajoute des fichiers image triés par ordre alphabétique dans un seul fichier PDF.

Certaines variables peuvent être définies dans le script. Cela dépend de ImageMagick et de pdftk.

NB: Si l'image d'entrée a une résolution supérieure (dpi) à la résolution souhaitée de output.pdf, l'image est rééchantillonnée à la résolution inférieure. Sinon, l'image n'est pas ré-échantillonnée et elle est uniquement étendue pour s'adapter au canevas de la page.

#!/bin/bash

export LOCALE=C

[[ "${2}x" == "x" ]] && \
 { echo "Usage: $( basename $0 ) output.pdf extension"
   echo "       merges all files (*.extension) into a single PDF"
   echo "If files z_merged.pdf, z_temp.pdf or $1 exist, they will be overwritten"
 exit 1
 } || \
 OutName="$1"
 ext="$2"

# Set basic variables
unset Debug #; Debug="yes" # print extra messages
IMBackground="white"      # what colour for paper
IMQuality="91"            # JPEG compression level
PaperWdthMetr="210"       # milimeters, 210 for ISO A4
PaperHghtMetr="297"       # milimeters, 297 for ISO A4
PaperDens="200"           # maximum (wanted) dpi for a page
PaperWdthInch=$( echo scale=5\; $PaperWdthMetr / 2.54 / 10      | bc -l ) # Inch
PaperHghtInch=$( echo scale=5\; $PaperHghtMetr / 2.54 / 10      | bc -l ) # Inch
PaperRtio=$(     echo scale=5\; $PaperWdthMetr / $PaperHghtMetr | bc -l )

# Remove temporary files from prior run
rm -rf z_merged.pdf z_temp.pdf 2>/dev/null

# Process any $ext file in the current directory
find . -maxdepth 1 -name "*.${ext}" -print0 | sort -z | while read -d '' -r FName
do
  echo "Converting $FName"
  ImgIdentify=$( identify -format "%w %h" "$FName" )
  ImgWdthOrig=$( echo $ImgIdentify | cut -d" " -f1  )
  ImgHghtOrig=$( echo $ImgIdentify | cut -d" " -f2  )
  ImgRtio=$( echo "scale=5; $ImgWdthOrig / $ImgHghtOrig"  | bc -l )
  [[ $( echo $ImgRtio'>'$PaperRtio | bc -l ) == 1 ]] \
    && ImgDens=$( echo scale=0\; $ImgWdthOrig / $PaperWdthInch | bc -l ) \
    || ImgDens=$( echo scale=0\; $ImgHghtOrig / $PaperHghtInch | bc -l )
  [[ $Debug ]] && echo "ImgDens1: $ImgDens"
  [[ $( echo $ImgDens'>'$PaperDens | bc -l ) == 1 ]] \
    && ImgDens=$PaperDens
  [[ $Debug ]] && echo "ImgDens2: $ImgDens"

  ImgWdth=$( echo $PaperWdthInch \* $ImgDens | bc -l ) # pixels
  ImgHght=$( echo $PaperHghtInch \* $ImgDens | bc -l ) # pixels

  [[ $Debug ]] && echo "ImgWdth: $ImgWdth".
  [[ $Debug ]] && echo "ImgHght: $ImgHght".

  convert "${FName}"                                 \
          -resize ${ImgWdth}x${ImgHght}              \
          -background $IMBackground -gravity center  \
          -extent ${ImgWdth}x${ImgHght}              \
          -units PixelsPerInch -set density $ImgDens \
          -repage ${ImgWdth}x${ImgHght}+0+0          \
          -compress JPEG                             \
          -quality $IMQuality                        \
          "${FName%.$ext}.pdf"

  # Merge new PDF page with prior pages
  [[ -f z_merged.pdf ]] && \
   { pdftk z_merged.pdf "${FName%.$ext}.pdf" cat output z_temp.pdf
     mv z_temp.pdf z_merged.pdf
   } || \
     cp "${FName%.$ext}.pdf" z_merged.pdf
  [[ $Debug ]] || rm -rf "${FName%.$ext}.pdf"
done

[[ -f z_merged.pdf ]] && mv z_merged.pdf "$OutName"
echo "Done."
Mikher
la source
Dans ce qui précède, je devais changer -set density $ImgDensen-density $ImgDens
Yotam
0

Je viens d'utiliser quelque chose de similaire à maxschlepzigs répondre sous Ubuntu 16.04 / ImageMagick

Cela centre également le résultat

i=300; convert a.png b.png -compress jpeg -quality 100 \
      -density ${i}x${i} -units PixelsPerInch \
      -resize $((i*827/100))x$((i*1169/100)) \
      -gravity center \
      -extent $((i*827/100))x$((i*1169/100)) multipage.pdf
Martin Thoma
la source
0

Je voulais convertir une image en taille de page de 5,00 x 8,00 po (vue depuis Adobe Reader) Voici ce que j'ai fait sous Ubuntu 18.04 OS. D'abord, déterminez la taille de la page que je recherche après:

$ pdfinfo my-input.pdf

Et le retour est: Taille de la page: 360 x 576 pts

Ensuite, l'image est convertie en un PDF de même taille, comme suit:

$ img2pdf --pagesize 360x576 -o outpage.pdf input_pic.jpg

Note: installer img2pdf

$ sudo apt install img2pdf

Harry
la source