通过直接包含 JPEG 将图像转换为 PDF。
项目描述
img2pdf
将光栅图像无损转换为 PDF。如果您的优先级是(按此顺序),则应使用 img2pdf:
- 始终无损:嵌入在 PDF 中的图像将始终具有与输入的每个像素完全相同的颜色信息
- small:如果可能,输入图像和输出 PDF 之间的文件大小差异只会是 PDF 容器本身的开销
- 快速:如果可能,输入图像只是按原样粘贴到 PDF 文档中,而不需要对像素数据进行任何 CPU 饥饿的重新编码
传统的转换软件(如 ImageMagick)会:
- 不是无损的,因为有损重新编码为 JPEG
- 不小,因为对原始像素数据使用了浪费的 flate 编码
- 不快,因为输入数据被重新编码
不必重新编码输入(在大多数常见情况下)的另一个优点是,img2pdf 能够处理比其他软件大得多的输入,因为原始像素数据永远不必加载到内存中。
下表显示了 img2pdf 如何根据输入文件格式和图像色彩空间处理不同的输入。
| 格式 | 色彩空间 | 结果 |
|---|---|---|
| JPEG | 任何 | 直接的 |
| JPEG2000 | 任何 | 直接的 |
| PNG(非隔行,无透明度) | 任何 | 直接的 |
| TIFF(CCITT 第 4 组) | 单色 | 直接的 |
| 任何 | 除 CMYK 和单色外的任何 | PNG帕斯 |
| 任何 | 单色 | CCITT 集团 4 |
| 任何 | CMYK | 平板 |
对于具有 CCITT Group 4 编码数据的 JPEG、JPEG2000、非隔行 PNG 和 TIFF 图像,img2pdf 直接将图像数据嵌入到 PDF 中,无需重新编码。因此,它仅将 PDF 格式视为图像数据的容器格式。在这些情况下,img2pdf 只会将文件大小增加 PDF 容器的大小(通常约为 500 到 700 个字节)。由于数据仅被复制而不是重新编码,因此对于这些输入格式,img2pdf 通常也比其他解决方案更快。
对于所有其他输入类型,img2pdf 首先必须转换像素数据以使其与 PDF 兼容。在大多数情况下,PNG Paeth 过滤器应用于像素数据。对于单色输入,改用 CCITT Group 4。仅对于 CMYK 输入,在最终应用平面压缩之前不应用过滤器。
用法
图像必须作为文件提供,因为 img2pdf 需要在文件描述符中查找。
如果没有使用-o/--output选项指定输出文件,则输出将完成到 stdout。一个典型的调用是:
$ img2pdf img1.png img2.jpg -o out.pdf
可以通过运行以下命令访问详细文档:
$ img2pdf --help
错误
-
如果您发现 JPEG、JPEG2000、PNG 或 CCITT Group 4 编码的 TIFF 文件在嵌入 PDF 时无法被 Adobe Acrobat Reader 读取,请与我联系。
-
如果输入图像损坏,则会产生错误。如果输入图像具有无效的 EXIF 方向值为零,则通常会发生这种情况。即使只允许从 1 到 9 的九个不同值,Anroid 手机和佳能 DSLR 相机也会生成无效值为零的 JPEG 图像。
exiftool在将 JPEG 传递给img2pdf或运行之前img2pdf使用或类似的软件修复输入图像--rotation=ifvalid(如果您从命令行运行 img2pdf),或者 在使用 img2pdf 作为库时rotation=img2pdf.Rotation.ifvalid作为参数传递给。convert() -
img2pdf 使用 PIL(或 Pillow)来获取图像元数据并在必要时转换输入。为了防止解压炸弹拒绝服务攻击,Pillow 限制了输入图像允许具有的最大像素数。如果您确定自己知道自己在做什么,则可以通过将
--pillow-limit-break选项传递给 img2pdf 来禁用此保护措施。这允许人们处理甚至非常大的输入图像。
安装
在基于 Debian 和 Ubuntu 的系统上,可以从官方存储库安装 img2pdf:
$ apt install img2pdf
如果你想使用 pip 安装它,你可以运行:
$ pip3 install img2pdf
如果您更喜欢从源代码安装,请使用:
$ cd img2pdf/
$ pip3 install .
要在系统上不安装软件包的情况下测试控制台脚本,请使用 virtualenv:
$ cd img2pdf/
$ virtualenv ve
$ ve/bin/pip3 install .
然后,您可以使用以下方法测试转换器:
$ ve/bin/img2pdf -o test.pdf src/tests/test.jpg
对于 Microsoft Windows 用户,基于 PyInstaller 的 .exe 文件由 appveyor 生成。如果您不想在使用 img2pdf 之前安装 Python,您可以前往 appveyor 并单击“Artifacts”下载最新版本: https ://ci.appveyor.com/project/josch/img2pdf
图形用户界面
存在一个实验性的 GUI,所有设置当前都被禁用。您可以直接将图像转换为 PDF,但您还不能通过 GUI 设置任何选项。如果您有兴趣为 PDF 添加更多功能,请提交合并请求。GUI 基于 tkinter,可在 Linux、Windows 和 MacOS 上运行。
图书馆
该包也可以用作库:
import img2pdf
# opening from filename
with open("name.pdf","wb") as f:
f.write(img2pdf.convert('test.jpg'))
# opening from file handle
with open("name.pdf","wb") as f1, open("test.jpg") as f2:
f1.write(img2pdf.convert(f2))
# using in-memory image data
with open("name.pdf","wb") as f:
f.write(img2pdf.convert("\x89PNG...")
# multiple inputs (variant 1)
with open("name.pdf","wb") as f:
f.write(img2pdf.convert("test1.jpg", "test2.png"))
# multiple inputs (variant 2)
with open("name.pdf","wb") as f:
f.write(img2pdf.convert(["test1.jpg", "test2.png"]))
# convert all files ending in .jpg inside a directory
dirname = "/path/to/images"
imgs = []
for fname in os.listdir(dirname):
if not fname.endswith(".jpg"):
continue
path = os.path.join(dirname, fname)
if os.path.isdir(path):
continue
imgs.append(path)
with open("name.pdf","wb") as f:
f.write(img2pdf.convert(imgs))
# convert all files ending in .jpg in a directory and its subdirectories
dirname = "/path/to/images"
imgs = []
for r, _, f in os.walk(dirname):
for fname in f:
if not fname.endswith(".jpg"):
continue
imgs.append(os.path.join(r, fname))
with open("name.pdf","wb") as f:
f.write(img2pdf.convert(imgs))
# convert all files matching a glob
import glob
with open("name.pdf","wb") as f:
f.write(img2pdf.convert(glob.glob("/path/to/*.jpg")))
# ignore invalid rotation values in the input images
with open("name.pdf","wb") as f:
f.write(img2pdf.convert('test.jpg'), rotation=img2pdf.Rotation.ifvalid)
# writing to file descriptor
with open("name.pdf","wb") as f1, open("test.jpg") as f2:
img2pdf.convert(f2, outputstream=f1)
# specify paper size (A4)
a4inpt = (img2pdf.mm_to_pt(210),img2pdf.mm_to_pt(297))
layout_fun = img2pdf.get_layout_fun(a4inpt)
with open("name.pdf","wb") as f:
f.write(img2pdf.convert('test.jpg', layout_fun=layout_fun))
# use a fixed dpi of 300 instead of reading it from the image
dpix = dpiy = 300
layout_fun = img2pdf.get_fixed_dpi_layout_fun((dpix, dpiy))
with open("name.pdf","wb") as f:
f.write(img2pdf.convert('test.jpg', layout_fun=layout_fun))
# create a PDF/A-1b compliant document by passing an ICC profile
with open("name.pdf","wb") as f:
f.write(img2pdf.convert('test.jpg', pdfa="/usr/share/color/icc/sRGB.icc"))
与 ImageMagick 的比较
创建一个大的测试图像:
$ convert logo: -resize 8000x original.jpg
使用 ImageMagick 和 img2pdf 将其转换为 PDF:
$ time img2pdf original.jpg -o img2pdf.pdf
$ time convert original.jpg imagemagick.pdf
请注意 ImageMagick 的转换时间比 img2pdf 长一个数量级。它还使用了两倍的内存。
现在从两个 PDF 文档中提取图像数据并将其与原始文件进行比较:
$ pdfimages -all img2pdf.pdf tmp
$ compare -metric AE original.jpg tmp-000.jpg null:
0
$ pdfimages -all imagemagick.pdf tmp
$ compare -metric AE original.jpg tmp-000.jpg null:
118716
为了使用 ImageMagick 获得无损输出,我们可以使用 Zip 压缩,但这会不必要地增加输出的大小:
$ convert original.jpg -compress Zip imagemagick.pdf
$ pdfimages -all imagemagick.pdf tmp
$ compare -metric AE original.jpg tmp-000.png null:
0
$ stat --format="%s %n" original.jpg img2pdf.pdf imagemagick.pdf
1535837 original.jpg
1536683 img2pdf.pdf
9397809 imagemagick.pdf
与 pdfLaTeX 的比较
pdfLaTeX 默认执行从包含的图像到 PDF 的无损转换。如果输入是 JPEG,那么它只是将 JPEG 嵌入到 PDF 中,就像 img2pdf 一样。但对于其他图像格式,它使用普通像素数据的平面压缩,因此不必要地增加了输出文件的大小:
$ convert logo: -resize 8000x original.png
$ cat << END > pdflatex.tex
\documentclass{article}
\usepackage{graphicx}
\begin{document}
\includegraphics{original.png}
\end{document}
END
$ pdflatex pdflatex.tex
$ stat --format="%s %n" original.png pdflatex.pdf
4500182 original.png
9318120 pdflatex.pdf
与 podofoimg2pdf 的比较
与 pdfLaTeX 一样,podofoimg2pdf 能够通过将 JPEG 数据简单地嵌入到 pdf 容器中来执行从 JPEG 到 PDF 的无损转换。但就像 pdfLaTeX 一样,它对所有其他文件格式使用 flate 压缩,因此有时会导致文件比需要的更大。
$ convert logo: -resize 8000x original.png
$ podofoimg2pdf out.pdf original.png
stat --format="%s %n" original.png out.pdf
4500181 original.png
9335629 out.pdf
它也只支持 JPEG、PNG 和 TIF 作为输入,缺乏 img2pdf 的许多便利功能,如页面大小、边框、旋转和元数据。
与 Tesseract OCR 的比较
Tesseract OCR 最接近 img2pdf 提供的功能。它能够将 JPEG 和 PNG 输入转换为 PDF,而无需不必要地增加文件大小,同时是无损的。因此,如果您的输入是 JPEG 和 PNG 图像,那么您应该可以安全地使用 Tesseract 而不是 img2pdf。对于其他输入,Tesseract 可能不会进行无损转换。例如,它将 CMYK 输入转换为 RGB,并从具有透明度的图像中移除 alpha 通道。对于多页 TIFF 或动画 GIF,它只会转换第一帧。