конвертировать изображения в PDF: Как сделать страницы PDF одного размера

Вопрос или проблема

Я сделал что-то вроде

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

Но первая страница значительно больше, чем последующие. Это происходит, несмотря на то, что размеры изображения схожи. Эти изображения отсканированы и обрезаны, поэтому могут иметь небольшие отличия в размерах

Я думал, что -page A4 должен фиксировать размер страниц?

Последний раз, когда я использовал 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)).

Изображения с линейной графикой

Если PNG-файлы являются двууровневыми (черно-белыми, т.е. линейными) изображениями, то инструмент img2pdf дает лучшие результаты по сравнению с ImageMagick convert. Это означает, что img2pdf быстрее и создает меньшие PDF-файлы.

Пример:

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

или:

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

Что вам действительно нужно использовать:

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

-extent фактически увеличивает изображение до 1240×1753, в то время как -resize сохраняет соотношение изображения, вписывая его либо в 1240x..., либо в ...x1753.

Параметр -gravity является необязательным, но может использоваться для центрирования изображения при расширении.

Дополнение к ответу caugners:

установив IM v6.6.9-7, я выяснил, что параметр -gravity должен быть расположен между -resize и -extent, чтобы иметь эффект.

дополнительно (хотя это не часть вопроса о.п.) я нашел настройку другого цвета фона привлекательной, что привело бы к общему синтаксису команды

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 (что является шириной в дюймах для A4 листа). параметр -repage a4 можно опускать большую часть времени, но у меня были случаи, когда результирующий .pdf имел другой формат, слегка отличающийся от размеров A4 210×297 мм (8.27×11.6″)

Я настоятельно рекомендую программу командной строки Python img2pdf для безубыточного преобразования:

https://gitlab.mister-muffin.de/josch/img2pdf

Пример использования:

img2pdf img1.png img2.png -o out.pdf --pagesize A4

Я нашел код Михера очень полезным, однако он полностью формирует PDF либо в портретной, либо в альбомной ориентации, поэтому я модифицировал его, чтобы проверить ориентацию каждого входного файла и соответствовать ей в выходном.

Я не включил редактирование Йотама, так как оно работает и без него на моем Ubuntu 15.04.

$#!/bin/bash

# Изменяет размер файлов до A4 (или другого размера - измените PaperWdthMetr и PaperHghtMetr ниже) и объединяет в PDF

export LOCALE=C

[[ "${2}x" == "x" ]] && \
 { echo "Использование: $( basename $0 ) output.pdf extension"
   echo "       объединяет все файлы (*.extension) в один PDF"
   echo "Если файлы z_merged.pdf, z_temp.pdf или $1 существуют, они будут перезаписаны"
 exit 1
 } || \
 OutName="$1"
 ext="$2"

# Установка базовых переменных
unset Debug #; Debug="yes" # печатать дополнительные сообщения
IMBackground="white"      # какой цвет для бумаги
IMQuality="91"            # уровень сжатия JPEG
PaperHghtMetr="297"       # миллиметры, 297 для ISO A4
PaperWdthMetr="210"       # миллиметры, 210 для ISO A4
PaperDens="200"           # максимальная (желаемая) dpi для страницы
PaperHInch=$( echo scale=5\; $PaperHghtMetr / 2.54 / 10      | bc -l ) # Дюйм
PaperWInch=$( echo scale=5\; $PaperWdthMetr / 2.54 / 10      | bc -l ) # Дюйм
PaperRtio=$(     echo scale=5\; $PaperWdthMetr / $PaperHghtMetr | bc -l )

# Удаление временных файлов из предыдущего запуска
rm -rf z_merged.pdf z_temp.pdf 2>/dev/null

# Обработка любых файлов с $ext в текущем каталоге
find . -maxdepth 1 -name "*.${ext}" -print0 | sort -z | while read -d '' -r FName
do
  echo "Конвертация $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 )

# Совпадение ориентации выходной страницы - альбомная или портретная - с входным файлом
  if (( $(echo "$ImgRtio > 1 && $PaperRtio > 1 || $ImgRtio < 1 && $PaperRtio < 1" |bc -l) )); then
    echo "Портрет"
    PaperHghtInch=$PaperHInch
    PaperWdthInch=$PaperWInch
  else
    echo "Альбом"
    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 ) # пиксели
  ImgHght=$( echo $PaperHghtInch \* $ImgDens | bc -l ) # пиксели

  [[ $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"

  # Объединение новой страницы PDF с предыдущими страницами
  [[ -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 "Готово."

Я использовал что-то подобное ответу maxschlepzig под 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

Я нахожу следующий скрипт удобным, который объединяет ответы, указанные здесь, а также некоторые проблемы, которые у меня были с вычислениями с плавающей точкой:

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 для лучшей точности.

Я тоже сталкивался с этой проблемой. Исходя из указанной информации, я написал скрипт, который добавляет по алфавиту отсортированные файлы изображений в один PDF.

Некоторые переменные можно задавать внутри скрипта. Он зависит от ImageMagick и pdftk.

Примечание: если входное изображение имеет более высокое разрешение (dpi), чем желаемое разрешение output.pdf, изображение ресэмплируется до более низкого разрешения. В противном случае изображение не ресэмплируется, а просто увеличивается, чтобы соответствовать размеру страницы.

#!/bin/bash

export LOCALE=C

[[ "${2}x" == "x" ]] && \
 { echo "Использование: $( basename $0 ) output.pdf extension"
   echo "       объединяет все файлы (*.extension) в один PDF"
   echo "Если файлы z_merged.pdf, z_temp.pdf или $1 существуют, они будут перезаписаны"
 exit 1
 } || \
 OutName="$1"
 ext="$2"

# Установка базовых переменных
unset Debug #; Debug="yes" # печатать дополнительные сообщения
IMBackground="white"      # какой цвет для бумаги
IMQuality="91"            # уровень сжатия JPEG
PaperWdthMetr="210"       # миллиметры, 210 для ISO A4
PaperHghtMetr="297"       # миллиметры, 297 для ISO A4
PaperDens="200"           # максимальная (желаемая) dpi для страницы
PaperWdthInch=$( echo scale=5\; $PaperWdthMetr / 2.54 / 10      | bc -l ) # Дюйм
PaperHghtInch=$( echo scale=5\; $PaperHghtMetr / 2.54 / 10      | bc -l ) # Дюйм
PaperRtio=$(     echo scale=5\; $PaperWdthMetr / $PaperHghtMetr | bc -l )

# Удаление временных файлов из предыдущего запуска
rm -rf z_merged.pdf z_temp.pdf 2>/dev/null

# Обработка любых файлов с $ext в текущем каталоге
find . -maxdepth 1 -name "*.${ext}" -print0 | sort -z | while read -d '' -r FName
do
  echo "Конвертация $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 ) # пиксели
  ImgHght=$( echo $PaperHghtInch \* $ImgDens | bc -l ) # пиксели

  [[ $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"

  # Объединение новой страницы PDF с предыдущими страницами
  [[ -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 "Готово."

Я хотел преобразовать изображение в размер страницы 5.00 x 8.00 дюймов (просмотрено в Adobe Reader) Вот что я сделал на Ubuntu 18.04. Сначала узнал размер страницы, который мне нужен следующим образом:

$ pdfinfo my-input.pdf

И ответ: Размер страницы: 360 x 576 pts

Затем изображение было преобразовано в PDF такого же размера следующим образом:

$ img2pdf –pagesize 360×576 -o outpage.pdf input_pic.jpg

Примечание: для установки img2pdf

$ sudo apt install img2pdf

Ответ или решение

Преобразование изображений в PDF: Как сделать размер страниц PDF одинаковым

Введение

Преобразование изображений в формат PDF является распространенной задачей для пользователей, занимающихся обработкой документов. Часто возникает необходимость сделать все страницы PDF одного размера, особенно когда исходные изображения имеют разные размеры и пропорции. В этом руководстве мы рассмотрим несколько эффективных методов достижения этого результата с использованием командной строки и специализированных программ.

Проблема с размерами страниц

Как показывает практика, при использовании команды convert из пакета ImageMagick, возникают трудности с размерами страниц PDF. Например, если вы используете следующую команду:

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

В результате первая страница может оказаться значительно больше, чем последующие, несмотря на схожесть размеров изображений. Это связано с тем, что картинки могут быть отсканированы и обрезаны с небольшими отклонениями в размерах.

Рекомендуемые подходы

  1. Использование опций resize и extent

    Для более точного контроля размеров страниц рекомендуется использовать параметры -resize и -extent. При этом -resize изменяет размеры изображений с сохранением пропорций, а -extent задаёт окончательный размер страницы.

    Пример команды:

    convert image1.png image2.png -compress jpeg -resize 1240x1753 \
           -gravity center -extent 1240x1753 -units PixelsPerInch \
           -density 150 multipage.pdf

    Здесь 1240×1753 пикселей соответствует размеру страницы A4 при разрешении 150 DPI. Параметр -gravity center используется для выравнивания изображений по центру.

  2. Использование img2pdf для линейных изображений

    Если ваши PNG файлы являются двуцветными (черно-белыми), популярным вариантом является использование программы img2pdf. Это приложение обеспечивает быструю и качественную конвертацию изображений в PDF без потери данных.

    Пример использования:

    img2pdf --pagesize A4 -o multipage.pdf image1.png image2.png
  3. Автоматизация процесса с помощью Bash-скрипта

    Для работы с большим количеством изображений вы можете создать Bash-скрипт, который автоматизирует процесс конвертации и перекраивает изображения под нужные размеры. Пример скрипта:

    #!/bin/bash
    
    output_name="$1"
    ext="$2"
    
    IMBackground="white"
    PaperWidth="210"  # ширина A4 в мм
    PaperHeight="297"  # высота A4 в мм
    
    find . -maxdepth 1 -name "*.${ext}" -print0 | sort -z | while read -d '' -r file; do
       convert "$file" -resize 1240x1753 -background $IMBackground \
               -gravity center -extent 1240x1753 -units PixelsPerInch \
               -density 150 "${file%.*}.pdf"
    done
    
    # Объединение всех PDF в один
    pdftk *.pdf cat output "$output_name"
    rm *.pdf
  4. Установка и настройка

    Для выполнения вышеприведенных команд требуется установка ImageMagick и других графических инструментов. На большинстве дистрибутивов Linux это можно сделать с помощью следующей команды:

    sudo apt install imagemagick pdftk

Заключение

В этой статье рассмотрены эффективные подходы к преобразованию изображений в PDF-документы с единообразием размеров страниц. Используя параметры команд convert и img2pdf, а также автоматизируя процессы через Bash-скрипты, вы сможете оптимизировать вашу работу с документами. Эти методы помогут избежать проблем с указанием разных размеров страниц и обеспечат профессиональный вид ваших PDF-документов.

Оцените материал
Добавить комментарий

Капча загружается...