如何将 .jpg 以 .pdf 为中心装入(使用定义的页面大小和边框)?

chr*_*coy 9 pdf imagemagick

我希望将 .jpg 转换为 .pdf,以便 .jpg 位于某个位置:以(例如)A4 页面为中心,图像和页面边框之间的最小边框为 30 像素。

我的起点就是这样(它只是创建一个与 JPG 大小相同的 PDF):

convert image.jpg image.pdf
Run Code Online (Sandbox Code Playgroud)

Mar*_*rco 10

我假设您想在所有四个边上添加一个 30px 的边框。使用-border尺寸和-bordercolor颜色选项:

convert -border 30 -bordercolor white input.png output.pdf
Run Code Online (Sandbox Code Playgroud)

可以在此处找到更多信息:Imagemagick - 添加/删除图像边缘

如果您希望最终的 PDF 具有特定大小,您可以使用以下选项:

convert \
  -page A4 \
  -gravity northwest \
  -border 30 \
  -bordercolor white \
  input.png output.pdf
Run Code Online (Sandbox Code Playgroud)


tan*_*ius 6

这是一个小脚本,可以执行您想要的操作,并且可以同时处理多个 .jpg 文件,将每个文件转换为自己的一页 .pdf 文件。

将脚本另存为imgs_to_pdfs.sh并使用一个或多个文件名参数调用它,如下所示:

./imgs_to_pdfs.sh myimg1.jpg myimg2.jpg img-*.jpg
Run Code Online (Sandbox Code Playgroud)

输出文件名将对应于输入文件名,其中 .jpg 替换为 .pdf。所以请确保脚本不会意外覆盖现有文件!

这个怎么运作

  • 对于装载图像的页面,脚本使用 A4 格式。它自己计算 A4 尺寸,因为最近的 ImageMagick 版本似乎不再支持 A4 关键字。
  • 图像不会被脚本重新采样(“缩放”),只是在 A4 PDF 页面画布上以特定分辨率居中显示。因此,不会因缩小而丢失图像信息,也不会因放大而增加无用的文件大小。
  • 该脚本在图像和 PDF 页面边框之间留出了一个空间,而不是四周的最小边距为 30 像素。与为图像添加白色边框相比,这样做的优势在于它不会增加文件大小,并且您可以稍后根据需要从 PDF 中提取未修改的图像,使用类似pdfimages -j file.pdf img.
  • 默认情况下,图像周围的边框将设置为每个页面尺寸的 ?5%。图像按比例缩放以实现此目的,因此 x 维度边框将为 5%,y 维度边框将更大,或者相反,具体取决于图像比例。您可以通过调整脚本中的分辨率因子来调整边框的大小。目前它是1.1,导致 A4 页面适合的分辨率为 110%。因此图像仅覆盖 A4 页面尺寸的 90%,留下两个 5% 的边框。如果将因子设置为1.2,则会得到两个 10% 的边框,依此类推。

其他详情

  • 以下是脚本中的公式如何导致 5% 边框的证明:
    1. 以像素为单位的页面大小计算为 page_size_x = density * 8.27
    2. 密度计算为density = img_size_x / 8.27 * 1.1。(这假设 x 维度需要更高的密度才能将 5% 的边框留空。)
    3. 第 1 行中的第 2 行产生:page_size_x = (img_size_x/8.27*1.1) * 8.27 = img_size_x * 1.1. 所以确实,页面是图像像素宽度的 110%,给出了两个 5% 的边框。
  • 有些人似乎需要一个-repage操作(比如这里)来防止页面大小稍微“偏离”。不需要它,但如果你这样做,请尝试-repage ${page_size_x}x${page_size_y}-repage A4作为convert调用中的最后一个操作。

脚本源代码

#!/bin/bash
# Converts input images to one-page PDF files each, without changing image data.
# The image is centered on a A4 page with a 5% border.

# bc function to calculate maximum of two floats
bc_functions="
define max(a,b) {
  if (a>b) {
    return(a)
  } else {
   return(b)
  }
} ";

for file in "$@"; do \
  # Determine image dimensions in pixels.
  img_size_x=$(identify -format "%w" "$file");
  img_size_y=$(identify -format "%h" "$file");

  # Calculate image density (in dpi) needed to fit the image and a 5% 
  # border all around on an A4 page (8.27x11.69"). Factor 1.1 creates 
  # 2*5% borders, see https://unix.stackexchange.com/a/220114 for details.
  min_density_x=$(echo "$img_size_x/8.27*1.1"  | bc -l);
  min_density_y=$(echo "$img_size_y/11.69*1.1" | bc -l);
  # Use the higher density to prevent any dimension exceeding the required fit.
  density=$(echo "$bc_functions max($min_density_x,$min_density_y)" | bc -l);

  # Calculate canvas dimensions in pixels.
  # (Canvas is an A4 page (8.27x11.69") with the calculated density.)
  page_size_x=$(echo  "8.27*$density" | bc -l);
  page_size_y=$(echo "11.69*$density" | bc -l);

  # Center image on a larger canvas (with a size given by "-extent").
  convert "$file" \
    -gravity center -extent ${page_size_x}x${page_size_y} \
    -units PixelsPerInch -density $density \
    -format pdf -compress jpeg \
    "${file/.jpg/.pdf}";
done;
Run Code Online (Sandbox Code Playgroud)

参考