converter imagens para pdf: como fazer páginas PDF do mesmo tamanho

38

Eu fiz algo parecido com

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

Mas a primeira página é muito maior do que as páginas subseqüentes. Isso acontece mesmo que as dimensões da imagem sejam semelhantes. Estas imagens são digitalizadas & recortado, portanto, pode ter pequenas diferenças nas dimensões

Eu achei que -page A4 deveria corrigir o tamanho das páginas?

    
por Jiew Meng 03.09.2011 / 06:02

7 respostas

53

A última vez que usei convert para essa tarefa, eu especifiquei explicitamente o tamanho do destino por meio do redimensionamento:

$ 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

O comando convert nem sempre usa DPI como unidade padrão de densidade / formato de página, portanto, especificamos explicitamente DPI com a opção -units (caso contrário, você poderá obter resultados diferentes com diferentes versões / combinações de formatos de entrada). O novo tamanho (especificado via -resize ) é a dimensão de uma página DIN A4 em pixels . O argumento de redimensionamento especifica o tamanho máximo da página. Qual resolução e qualidade escolher exatamente depende do caso de uso - selecionei 150 DPI e a qualidade média para economizar espaço enquanto não parece tão ruim quando impresso em papel.

Observe que convert por padrão não altera a proporção com a operação de redimensionamento:

Resize will fit the image into the requested size. It does NOT fill, the requested box size.

( Manual do ImageMagick )

Dependendo da versão do ImageMagick e dos formatos de entrada envolvidos, pode ser ok omitir a opção -repage . Mas às vezes é necessário e sem essa opção o cabeçalho do PDF pode conter dimensões muito pequenas. Em qualquer caso, o -repage não deve doer.

Os cálculos usam aritmética inteira, já que bash apenas suporta isso. Com zsh , as expressões podem ser simplificadas, ou seja, substituídas por $((i*8.27))x$((i*11.69)) .

Imagens Lineart

Se os arquivos PNG tiverem imagens de dois níveis (preto e branco também), a img2pdf tool produz resultados superiores ao ImageMagick convert . Isso significa que img2pdf é mais rápido e produz PDFs menores.

Exemplo:

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

ou:

$ img2pdf --pagesize A4 -o multipage.pdf a.png b.png
    
por 03.09.2011 / 20:02
20

O que você realmente quer usar é:

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

-extent na verdade amplia a imagem para 1240x1753, enquanto -resize mantém a proporção da imagem, ajustando-a em 1240x... ou ...x1753 .

O parâmetro -gravity é opcional, mas pode ser usado para centralizar a imagem ao se estender.

    
por 07.05.2013 / 14:45
9

Além da resposta do caugner :

tendo instalado o IM v6.6.9-7, descobri que o parâmetro -gravity precisa ser colocado entre -resize e -extent para ter um efeito.

adicionalmente (embora não faça parte da questão da o.p.) eu achei a configuração de uma cor de fundo diferente atraente que resultaria no comando total de

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

outra variação útil que eu geralmente uso quando não quero redimensionar uma imagem que já vem na proporção correta, mas mantenha sua resolução individual

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

onde a densidade de destino é determinada dinamicamente calculando a largura dividida por 8,27 (que é a largura em polegada de uma página A4). o parâmetro -repage a4 pode ser omitido a maior parte do tempo, mas eu tive alguns casos em que o .pdf resultante teria um formato diferente das dimensões A4 de 210x297mm (8.27x11.6 ")

    
por 17.09.2013 / 21:37
2

Eu achei o código de Mikher muito útil, no entanto, ele coloca o PDF inteiramente como Portrait ou Landscape, então eu o modifiquei para verificar o layout de cada arquivo de entrada e combiná-lo na saída.

Eu não incluí a edição do Yotam, pois funciona sem ela na minha caixa do 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."
    
por 01.11.2015 / 05:42
2

Eu acho o seguinte script conveniente, que combina as respostas listadas aqui, bem como alguns problemas que tive com o cálculo do ponto flutuante:

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"

O script é chamado (salvo como arquivo images2pdf)

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

/ edit: Adicionado o sinalizador "-l" de acordo com o comentário de tanius para melhor precisão.

    
por 26.06.2014 / 10:08
1

Eu estava lutando com essas coisas também. Com base nas informações acima, eu escrevi um script que adiciona arquivos de imagem classificados em ordem alfabética em um único PDF.

Algumas variáveis são configuráveis dentro do script. Depende do ImageMagick e do pdftk.

NB: Se a imagem de entrada tiver uma resolução mais alta (dpi) do que a resolução desejada de output.pdf, a imagem será redimensionada para a resolução mais baixa. Caso contrário, a imagem não será reamostrada e só será estendida para caber na tela da 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."
    
por 26.05.2014 / 23:17
0

Acabei de usar algo semelhante à resposta do maxschlepzigs no Ubuntu 16.04 / ImageMagick

Isso também centraliza o 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
    
por 14.09.2017 / 20:22