convertir imágenes a pdf: Cómo hacer páginas PDF del mismo tamaño


45

Hice algo como

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

Pero la primera página es mucho más grande que las páginas siguientes. Esto sucede a pesar de que las dimensiones de la imagen son similares. Estas imágenes se escanean y recortan, por lo que pueden tener ligeras diferencias en las dimensiones.

¿Pensé que -page A4debería arreglar el tamaño de las páginas?

Respuestas:


60

La última vez que utilicé convertpara tal tarea, especifiqué explícitamente el tamaño del destino mediante el cambio de tamaño:

$ 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

El convertcomando no siempre usa DPI como unidad de densidad / formato de página predeterminada, por lo tanto, especificamos explícitamente DPI con la -unitsopción (de lo contrario, puede obtener resultados diferentes con diferentes versiones / combinaciones de formatos de entrada). El nuevo tamaño (especificado mediante -resize) es la dimensión de una página DIN A4 en píxeles. El argumento de cambio de tamaño especifica el tamaño máximo de página. Qué resolución y calidad elegir exactamente depende del caso de uso: seleccioné 150 DPI y calidad promedio para ahorrar algo de espacio mientras no se ve tan mal cuando se imprime en papel.

Tenga en cuenta que, convertpor defecto, no cambia la relación de aspecto con la operación de cambio de tamaño:

Cambiar el tamaño se ajustará a la imagen en el tamaño solicitado. NO llena, el tamaño de caja solicitado.

( Manual de ImageMagick )

Dependiendo de la versión de ImageMagick y los formatos de entrada involucrados, podría estar bien omitir la -repageopción. Pero a veces es obligatorio y sin esa opción, el encabezado del PDF podría contener dimensiones demasiado pequeñas. En cualquier caso, el -repageno debería doler.

Los cálculos usan aritmética de enteros ya que bashsolo es compatible con eso. Con zshlas expresiones se puede simplificar, es decir, reemplazar con $((i*8.27))x$((i*11.69)).

Lineart Images

Si los archivos PNG son imágenes de dos niveles (también conocido como lineart en blanco y negro), la img2pdfherramienta produce resultados superiores sobre ImageMagick convert. Eso significa que img2pdfes más rápido y produce archivos PDF más pequeños.

Ejemplo:

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

o:

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

2
cuando uso -repage a4obtengo uninvalid argument for option '-repage': a4
Scolytus

1
@Scolytus, en un sistema Fedora 19, he observado un problema similar: parece que -repageya no es compatible con el nombre a4. He trabajado alrededor de esto a través de la aritmética de shell:-repage $((150*8.27))x$((150*11.69))
maxschlepzig

¿Supongo que esos números mágicos son 150 ppp y A4 expresados ​​en unidades heredadas?
Michael Scheper

@ MichaelScheper, sí, ppp y pulgadas.
maxschlepzig

Gracias ayúdame. En realidad, -density 150era importante agregar un argumento.
dma_k

23

Lo que realmente quieres usar es:

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

-extenten realidad extiende la imagen para que sea 1240x1753, mientras -resizemantiene la proporción de la imagen, ajustándola en 1240x...o ...x1753.

El -gravityparámetro es opcional pero se puede usar para centrar la imagen cuando se extiende.


1
¡Gracias! -extentes realmente lo que quiero usar :) - por favor, agregue la cita izquierda perdida delante de - extensión, ¡gracias!
brownian

¡Gracias, eventualmente agregué la marca faltante! ;-)
caugner

9

Además de la respuesta de Caugner :

Después de instalar IM v6.6.9-7 descubrí que el -gravityparámetro debe colocarse en el medio -resizey -extenttener un efecto.

Además (aunque no es parte de la pregunta operativa), encontré que establecer un color de fondo diferente era atractivo, lo que resultaría en el comando total de

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

Otra variación útil que uso a menudo cuando no quiero volver a escalar una imagen que ya viene en la relación de aspecto correcta, pero mantener su resolución individual es

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

donde la densidad objetivo se determina dinámicamente calculando el ancho dividido por 8.27 (que es el ancho en pulgadas de una página A4). el -repage a4parámetro se puede omitir la mayor parte del tiempo, pero he tenido algunos casos en los que el .pdf resultante tendría un formato diferente a las dimensiones A4 de 210x297 mm (8.27x11.6 ")


2

Encontré el código de Mikher muy útil, sin embargo, presenta el PDF completamente como Vertical u Horizontal, por lo que lo modifiqué para verificar el diseño de cada archivo de entrada y hacer que coincida en la salida.

No incluí la edición de Yotam, ya que funciona sin ella en mi caja 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."

2

Me parece conveniente el siguiente script que combina las respuestas enumeradas aquí, así como algunos problemas que tuve con el cálculo de coma flotante:

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"

Se llama al script (guardado como un archivo images2pdf)

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

/ edit: Se agregó el indicador "-l" según el comentario de tanius para una mejor precisión


Sugerencia general: $(echo "150*8.27" | bc)todavía no es excelente para coma flotante. Funciona aquí porque es una multiplicación. Sin $(echo "150/8.27" | bc)embargo, el resultado es 18(truncado a entero). En cambio, llame bccon mayor scale: $(echo "150/8.27" | bc -l)los resultados son 18.137847….
tanius

1

Yo también estaba luchando con esas cosas. Basado en la información anterior, escribí un script que agrega archivos de imagen ordenados alfabéticamente en un solo PDF.

Algunas variables son configurables dentro del script. Depende de ImageMagick y pdftk.

Nota: si la imagen de entrada tiene una resolución más alta (ppp) que la resolución deseada de output.pdf, la imagen se muestrea a la resolución más baja. De lo contrario, la imagen no se vuelve a muestrear y solo se extiende para adaptarse al lienzo de la página.

#!/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."

En lo anterior, tuve que cambiarme -set density $ImgDensa-density $ImgDens
Yotam


0

Acabo de usar algo similar a la respuesta maxschlepzigs en Ubuntu 16.04 / ImageMagick

Esto también centra el resultado

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

0

Quería convertir una imagen al tamaño de página de 5.00 x 8.00 pulgadas (visto desde Adobe Reader) Esto es lo que hice en ubuntu 18.04 OS. Primero, averigua el tamaño de página que busco así:

$ pdfinfo my-input.pdf

Y el retorno es: Tamaño de página: 360 x 576 pts

Luego, la imagen se convierte a un PDF del mismo tamaño de la siguiente manera:

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

Nota: para instalar img2pdf

$ sudo apt install img2pdf

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.