it-swarm.cn

将图像转换为pdf:如何制作PDF页面大小相同

我做了类似的事情

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

但是第一页比后续页大得多。即使图像尺寸相似,也会发生这种情况。这些图像被扫描并裁剪,因此尺寸可能略有不同

我想 -page A4应该确定页面的大小吗?

47
Jiew Meng

上次我使用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 [〜#〜] 作为默认的密度/页面格式单位,因此我们使用-units选项显式指定了DPI(否则使用不同的版本/输入格式组合可能会得到不同的结果)。新的大小(通过-resize指定)是 DIN A4页面的尺寸 以像素为单位。 resize参数指定最大页面大小。确切选择哪种分辨率和质量取决于使用情况-我选择了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
63
maxschlepzig

您真正想要使用的是:

$ 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参数是可选的,但在扩展时可用于使图像居中。

25
caugner

除了 caugner的答案

安装了IM v6.6.9-7后,我发现-gravity参数需要放在-resize-extent之间才能生效。

另外(虽然不是o.p.问题的一部分),我发现设置了一种不同的背景色吸引人的效果,这将导致

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尺寸210x297mm(8.27x11.6“)截然不同

9
antiplex

我发现以下脚本很方便,它结合了此处列出的答案以及浮点计算所遇到的一些问题:

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

/ edit:根据tanius的注释添加了“ -l”标志,以实现更高的精度。

2
rindPHI

我强烈建议Python CLI程序img2pdf进行无损转换:

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

用法示例:

img2pdf img1.png img2.png -o out.pdf
2
Adam Erickson

我发现Mikher的代码非常有用,但是它将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
user173283

我也在那东西上挣扎。基于以上信息,我编写了一个脚本,该脚本将按字母顺序排序的图像文件添加到单个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."
1
Mikher

我只是在Ubuntu 16.04/ImageMagick下使用类似于maxschlepzigs答案的东西

这也将结果居中

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
Martin Thoma

我想将图像转换为5.00 x 8.00 in(从Adobe Reader中查看)的页面大小,这是我在ubuntu 18.04 OS上所做的。首先,找出我想要的页面大小,如下所示:

$ pdfinfo my-input.pdf

返回的是:页面大小:360 x 576点

然后将图像转换为大小相同的PDF

$ img2pdf-页面大小360x576 -o outpage.pdf input_pic.jpg

注意:安装img2pdf

$ Sudo apt安装img2pdf

0
Harry