converter imagens em pdf: Como criar páginas PDF do mesmo tamanho

45

Eu fiz algo como

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

Mas a 1ª página é muito maior que as páginas subseqüentes. Isso acontece mesmo que as dimensões da imagem sejam semelhantes. Essas imagens são digitalizadas e cortadas, portanto, podem ter pequenas diferenças nas dimensões

Eu pensei que -page A4deveria corrigir o tamanho das páginas?

Jiew Meng
fonte

Respostas:

60

A última vez que usei convertpara essa tarefa, especifiquei explicitamente o tamanho do destino via 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 convertcomando nem sempre usa o DPI como unidade padrão de densidade / formato de página; portanto, especificamos explicitamente o DPI com a -unitsopção (caso contrário, você poderá obter resultados diferentes com diferentes combinações de versões / 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 qualidade média para economizar espaço, embora não pareça muito ruim quando impresso em papel.

Observe que, convertpor padrão, não altera a proporção da imagem com a operação de redimensionamento:

Redimensionar ajustará a imagem ao tamanho solicitado. NÃO preenche, o tamanho da caixa solicitada.

( Manual ImageMagick )

Dependendo da versão do ImageMagick e dos formatos de entrada envolvidos, pode ser correto omitir a -repageopção. Às vezes, porém, é necessário e, sem essa opção, o cabeçalho do PDF pode conter dimensões muito pequenas. De qualquer forma, -repagenão deve doer.

Os cálculos usam aritmética inteira, uma vez que bashapenas suporta isso. Com zshas expressões podem ser simplificadas - ou seja, substituídas por $((i*8.27))x$((i*11.69)).

Imagens de Lineart

Se os arquivos PNG forem imagens em dois níveis (preto e branco, também conhecido como linear), a img2pdfferramenta produzirá 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
maxschlepzig
fonte
2
ao usar -repage a4eu recebo uminvalid argument for option '-repage': a4
Scolytus
1
@ Scolytus, em um sistema Fedora 19, observei um problema semelhante - parece que -repageele não suporta mais o nome a4. Eu trabalhei em torno desta via aritmética shell:-repage $((150*8.27))x$((150*11.69))
maxschlepzig
Presumo que esses números mágicos sejam 150 dpi e A4 expressos em unidades herdadas?
Michael Scheper
@MichaelScheper, sim, dpi e polegadas.
maxschlepzig
Obrigado, me ajude. Na verdade, -density 150era importante acrescentar argumentos.
dma_k
23

O que você realmente deseja usar é:

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

-extentna verdade, estende a imagem para 1240x1753, enquanto -resizemantém a proporção da imagem, ajustando-a em um 1240x...ou em ...x1753.

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

caugner
fonte
1
Obrigado! -extenté realmente o que eu quero usar :) - por favor, adicione a citação esquerda perdida na frente de -extent, obrigado!
brownian 17/05
Obrigado, eventualmente adicionei o carrapato que faltava! ;-)
caugner
9

Além da resposta de caugner :

depois de instalar o IM v6.6.9-7, descobri que o -gravityparâmetro precisa ser colocado no meio -resizee -extentter efeito.

Além disso (embora não faça parte da pergunta operacional), achei a definição de um recurso de cor de fundo diferente, o 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 costumo usar quando não quero redimensionar uma imagem que já vem na proporção correta, mas mantém 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 polegadas de uma página A4). o -repage a4parâmetro pode ser omitido na maioria das vezes, mas tive alguns casos em que o .pdf resultante teria um formato diferente ligeiramente das dimensões A4 de 210x297mm (8,27x11,6 ")

antiplex
fonte
2

Achei o código de Mikher muito útil, no entanto, ele expõe o PDF inteiramente como Retrato ou Paisagem, então eu o modifiquei para verificar o layout de cada arquivo de entrada e combiná-lo na saída.

Não incluí a edição do Yotam, pois ela 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."
user173283
fonte
2

Acho conveniente o seguinte script, que combina as respostas listadas aqui, além de alguns problemas que tive com o cálculo de 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 um arquivo images2pdf)

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

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

rindPHI
fonte
Dica geral: $(echo "150*8.27" | bc)ainda não é ótimo para ponto flutuante. Funciona aqui porque é uma multiplicação. Pois $(echo "150/8.27" | bc), o resultado é 18(truncado para inteiro). Em vez disso, ligue bccom mais alto scale:, $(echo "150/8.27" | bc -l)os resultados são 18.137847….
tanius
1

Eu também estava lutando com essas coisas. Com base nas informações acima, 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.

Nota: Se a imagem de entrada tiver uma resolução mais alta (dpi) que a resolução desejada de output.pdf, a imagem será reamostrada para a resolução mais baixa. Caso contrário, a imagem não será amostrada novamente e somente 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."
Mikher
fonte
No exposto, eu tive que mudar -set density $ImgDenspara-density $ImgDens
Yotam
0

Acabei de usar algo semelhante à resposta 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
Martin Thoma
fonte
0

Eu queria converter uma imagem em um tamanho de página de 5,00 x 8,00 polegadas (visualizado no Adobe Reader) Aqui está o que eu fiz no sistema operacional ubuntu 18.04. Primeiro, descubra o tamanho da página que eu procuro da seguinte forma:

$ pdfinfo my-input.pdf

E o retorno é: Tamanho da página: 360 x 576 pts

Em seguida, a imagem é convertida em um PDF do mesmo tamanho da seguinte forma:

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

Nota: para instalar o img2pdf

$ sudo apt install img2pdf

atormentar
fonte