конвертувати зображення в pdf: як зробити PDF-сторінки однаковими за розміром


45

Я щось подібне зробив

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

Але 1-а сторінка значно більша, ніж наступні. Це відбувається, навіть якщо розміри зображення схожі. Ці зображення відскановані та обрізані, таким чином можуть мати незначні відмінності в розмірах

Я думав, чи -page A4слід виправити розмір сторінок?

Відповіді:


60

Востаннє, коли я використовував convertтаке завдання, я чітко вказав розмір пункту призначення шляхом зміни розміру:

$ 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

convertКоманда не завжди використовує DPI в якості одиниці формату щільності по замовчуванням / сторінки, таким чином , ми явно вказати DPI з -unitsопцією ( в іншому випадку ви можете отримати різні результати з різними версіями комбінацій / формату вхідного сигналу). Новий розмір (вказаний через -resize) - це розмір сторінки DIN A4 у пікселях. Аргумент зміни розміру визначає максимальний розмір сторінки. Яку роздільну здатність та якість вибрати саме залежно від випадку використання - я вибрав 150 DPI та середню якість, щоб заощадити місце, хоча він не надто погано виглядає при друкуванні на папері.

Зауважте, що convertза замовчуванням не змінюється співвідношення сторін під час операції зміни розміру:

Змінити розмір буде відповідати зображенню до потрібного розміру. Він НЕ заповнює, потрібний розмір поля.

( Посібник із ImageMagick )

Залежно від версії ImageMagick і відповідних форматів введення, можливо, буде пропустити цю -repageопцію. Але іноді це потрібно і без цієї опції заголовок PDF може містити занадто малі розміри. У будь-якому випадку, -repageне слід шкодити.

Для обчислень використовується ціла арифметика, оскільки це bashлише підтримує. За zshдопомогою виразів можна спростити - тобто замінити на $((i*8.27))x$((i*11.69)).

Lineart Зображення

Якщо файли PNG мають дворівневі (чорно-білі ака-lineart) зображення, то img2pdfінструмент дає чудові результати порівняно з ImageMagick convert. Це означає, що img2pdfце швидше і отримує менші PDF-файли.

Приклад:

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

або:

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

2
при використанні -repage a4я отримуюinvalid argument for option '-repage': a4
Scolytus

1
@Scolytus, в системі Fedora 19 я спостерігав подібну проблему - схоже, -repageвона вже не підтримує назву a4. Я працював над цим через арифметику оболонки:-repage $((150*8.27))x$((150*11.69))
maxschlepzig

Я припускаю, що ці магічні цифри - 150 dpi, а A4 виражений у спадщині?
Майкл Шепер

@MichaelScheper, так, dpi та дюйми.
maxschlepzig

Спасибі, допоможіть мені. Власне -density 150аргумент було важливо додати.
dma_k

23

Що ви дійсно хочете використовувати:

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

-extentнасправді розширює зображення на 1240x1753, при цьому -resizeзберігає співвідношення зображення, вписуючи його в 1240x...або ...x1753.

-gravityПараметр є необов'язковим , але може бути використаний для розміщення зображення при розширенні.


1
Дякую! -extentце дійсно те, що я хочу використовувати :) - будь ласка, додай пропущену ліву цитату перед -extent, дякую!
броунів

Дякую, я врешті додав відсутню галочку! ;-)
caugner

9

Доповнення до відповіді заспокоювача :

встановивши IM v6.6.9-7, я з’ясував, що -gravityпараметр потрібно розмістити між ними -resizeта -extentмати ефект.

додатково (хоча це не є частиною запитання op), я знайшов налаштування іншого кольору фону привабливим, що призведе до загальної команди

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

інший корисний варіант, який я часто використовую, коли я не хочу переробляти масштаб зображення, яке вже надходить у правильному співвідношенні сторін, але зберігати його індивідуальну роздільну здатність

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

де щільність цілі динамічно визначається шляхом обчислення ширини, поділеної на 8,27 (що становить ширину в дюймі сторінки А4). цей -repage a4параметр може бути опущений більшу частину часу, але у мене було кілька випадків, коли отриманий .pdf мав би інший формат, неглибоко від розмірів А4 210x297 мм (8,27x11,6 ")


2

Я вважав код Міхера дуже корисним, проте він викладає PDF цілком як портрет або пейзаж, тому я змінив його, щоб перевірити макет кожного вхідного файлу та відповідати його у вихідному.

Я не включив редактор Yotam, оскільки він працює без нього на моєму вікні 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

Наступний сценарій мені здається зручним, що поєднує в собі перераховані тут відповіді, а також деякі проблеми, які виникли у мене з розрахунком плаваючої точки:

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"

Сценарій викликається (зберігається як файл images2pdf)

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

/ редагувати: Додано прапор "-l" згідно з коментарем tanius для кращої точності.


Загальний натяк: $(echo "150*8.27" | bc)все ще не підходить для плаваючої точки. Тут працює, тому що це множення. Бо $(echo "150/8.27" | bc)хоч результат є 18(усічений до цілого числа). Натомість дзвоніть bcз вищими scale:, $(echo "150/8.27" | bc -l)результати є 18.137847….
таніус

1

Я теж боровся з цими речами. На підставі вищезазначеної інформації я написав сценарій, який додає алфавітно відсортовані файли зображень в один PDF.

Деякі змінні можна встановити всередині сценарію. Це залежить від ImageMagick та pdftk.

Примітка: Якщо вхідне зображення має більш високу роздільну здатність (dpi), ніж шукана роздільна здатність output.pdf, зображення перекомпонується на нижчу роздільну здатність. В іншому випадку зображення не переутворюється, а воно лише розширюється для розміщення сторінки на полотні.

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

У вищесказаному мені довелося перейти -set density $ImgDensна-density $ImgDens
Йотам


0

Я просто використав щось подібне до відповіді maxschlepzigs під Ubuntu 16.04 / ImageMagick

Це також центрує результат

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.