三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

图片转PDF最简单的方法:img2pdf 图像转PDF工具无损快速上手指南

图片转PDF最简单的方法:img2pdf 图像转PDF工具无损快速上手指南

图片转PDF最简单的方法:img2pdf 图像转PDF工具无损快速上手指南

【免费下载链接】img2pdfmirror of https://gitlab.mister-muffin.de/josch/img2pdf for Travis and appveyor CI项目地址: https://gitcode.com/gh_mirrors/im/img2pdf

你有没有过这种时刻:手里攒了几十张图,客户或老板说"打包成一个PDF发我",结果你用在线工具转了半小时,传上去不是报错就是画质糊成一片,最后只能硬着头皮拿截图重新拼?如果你正在为"图片转PDF"这件事头疼,那么今天要介绍的 img2pdf——一个主打无损、小巧、快速的图像转PDF工具——很可能是你一直在找的答案。

它不是那种包装华丽的商业软件,而是一个开源命令行工具兼 Python 库,靠着"无损转换"这一条硬核承诺,在摄影、设计、科研和文档归档圈子里口碑极好。下面我们就从最实际的场景聊起,看看它凭什么能帮你把"交图"这件事变得又快又体面。

交图前最后一分钟,为什么总卡在"转PDF"这一步?

想象几个高频场景:

  • 电商运营要把上百张产品图合成一本目录 PDF,上传平台要求必须是 PDF;
  • 设计师要给客户交付作品集,客户希望一个文件搞定,不要一坨散图;
  • 科研党投稿期刊,编辑明确要求配图必须嵌入在 PDF 里且不能被压缩成马赛克。

这些场景的共同点是:图片质量不能丢,文件不能太大,速度还不能慢。可传统办法偏偏在这三点上集体翻车。

拿最常见的 ImageMagick 来说,convert a.jpg out.pdf会把像素数据重新编码一遍:要么为了压体积做有损压缩,画质悄悄缩水;要么为了保无损用笨重的 flate 编码,结果 PDF 比原图大了好几倍;而且每张图都要重算一遍像素,图一多就慢得让人抓狂。你等于让工具把图片"重新煮熟"再塞进 PDF——费时费力,还可能煮坏。

img2pdf 的思路完全不同,一句话就能说清:能直接搬的图,它连包装都不拆,原样搬进 PDF

它和笨办法的差别:一个在"搬家",一个在"重装修"

很多人第一反应是:转 PDF 不就是"套个壳"吗,能有多大差别?还真有,而且差别就是它的全部价值。

对于 JPEG、JPEG2000、非交错的 PNG、用 CCITT Group 4 编码的单色 TIFF,以及单页通用编码的 JBIG2 这类输入,img2pdf 会把原始图像字节原封不动地嵌入 PDF,把 PDF 纯粹当成一个容器。像素数据既不重编码也不重采样,所以:

  1. 永远无损——PDF 里每个像素的颜色信息,和输入图片一模一样;
  2. 体积接近原图——输出只比输入多出 PDF 容器本身的开销,通常只有 500~700 字节;
  3. 速度快得离谱——因为只在"搬数据",不需要 CPU 去重新压缩,甚至能比 ImageMagick 快一个数量级,内存占用也更低。

听起来很玄?做个最简单的验证你就信了:转一张 JPG,然后ls -l对比原图和 PDF 的大小,你会看到两者几乎一样大——这就是"无损"最直观的证据。

当然,不是所有格式都能享受"直搬"待遇。img2pdf 的处理策略大概是这样的:

输入情况处理方式
JPEG / JPEG2000 / 非交错PNG / CCITT G4 的TIFF / 单页JBIG2直接嵌入,不重编码
其他格式(除 CMYK 和 1 位单色)套用 PNG Paeth 过滤再压缩
1 位单色图转成 CCITT Group 4 编码
CMYK 图用 flate 压缩

看到没,只有当输入格式 PDF"不认"时,它才不得不做转换——这也是后面"避坑"章节会提到的一个关键点。

三步把照片变成 PDF:装、转、验

别急着研究高级功能,先跑通最小闭环。下面三步每一步都是可以直接复制的命令。

第一步:安装(三选一)

最省事的是用 pip:

pip3 install img2pdf

Debian / Ubuntu 用户也可以走系统源:

apt install img2pdf

想从源码体验最新版,就把仓库克隆下来装:

git clone https://gitcode.com/gh_mirrors/im/img2pdf cd img2pdf pip3 install .

第二步:转出人生第一份 PDF

装好后随便拿一张你自己的图,或者干脆用这个项目自带的测试图(就在src/tests/input/目录里):

img2pdf src/tests/input/normal.jpg -o 我的第一份.pdf

如果想一次合并多张图,也很直白:

img2pdf 图1.jpg 图2.png 图3.tiff -o 合并.pdf

第三步:验收——无损不是嘴上说说的

先看体积:

ls -l src/tests/input/normal.jpg 我的第一份.pdf

你会看到 PDF 只比原图大几百字节。如果装了 poppler-utils 和 ImageMagick,还能做更硬核的验证:把 PDF 里的图抽回来,和原图逐像素对比,输出 0 表示一个像素都不差:

pdfimages -all 我的第一份.pdf extracted compare -metric AE src/tests/input/normal.jpg extracted-000.jpg null:

没装这些工具也没关系,看体积差就已经很有说服力了。

三个高频技巧,让 PDF 更上得了台面

跑通之后,接下来这三个能力是日常使用中出现频率最高的,值得马上记下来。

技巧一:指定页面尺寸,告别"图多大页多大"

默认情况下,PDF 页面和图片一样大,图片刚好铺满整页。但如果你要打印、装订或者上传到要求 A4 的平台,就需要固定页面尺寸。

命令行一行搞定:

img2pdf 海报.jpg --pagesize A4 -o A4版.pdf

用 Python 库也一样,关键是mm_to_pt这个把毫米换算成 PDF 单位的工具函数:

import img2pdf # 定义 A4 尺寸:宽 210mm,高 297mm a4 = (img2pdf.mm_to_pt(210), img2pdf.mm_to_pt(297)) layout = img2pdf.get_layout_fun(a4) with open("A4版.pdf", "wb") as f: f.write(img2pdf.convert("海报.jpg", layout_fun=layout))

技巧二:手机竖拍的照片方向不对?一个参数搞定

这是很多人第一次用 img2pdf 就撞上的坑:安卓手机和部分佳能相机拍出的 JPEG,EXIF 方向值可能是 0——而合法值只有 1 到 9,等于写了个"无效答案",工具直接报错。

别急着修图,img2pdf 自己就能兜底:

img2pdf --rotation=ifvalid 手机拍的.jpg -o 方向修正.pdf

Python 写法对应是rotation=img2pdf.Rotation.ifvalid

import img2pdf with open("方向修正.pdf", "wb") as f: f.write(img2pdf.convert("手机拍的.jpg", rotation=img2pdf.Rotation.ifvalid))

技巧三:整目录批量转,一套循环全带走

几十张图一张张敲命令太蠢了。用 Python 库配合 glob,三行代码搞定"批量图片转PDF":

import img2pdf import glob # 收集目录下所有 jpg,按文件名排序保证页面顺序稳定 图片列表 = sorted(glob.glob("产品图/*.jpg")) with open("批量合并.pdf", "wb") as f: f.write(img2pdf.convert(图片列表))

顺带一提:动图 GIF 和多页 TIFF 默认会"每帧一页"全部转进去,如果你只想要第一帧,命令行加--first-frame-only即可。

两个实战场景,代码直接抄

下面两个例子覆盖了最常见的两类需求,代码都是完整可跑的,拿去改改路径就能用。

实战一:给电商产品目录一键排版

假设每个产品一个文件夹,里面有多个角度的照片,你想把它们按产品名排序合成一本目录:

import img2pdf import glob import os def build_catalog(folder, output): # 收集所有产品文件夹里的 jpg 照片 images = sorted(glob.glob(os.path.join(folder, "*", "*.jpg"))) if not images: print("没有找到图片,检查一下路径") return with open(output, "wb") as f: f.write(img2pdf.convert(images)) print(f"完成:{len(images)} 张图片已合成 -> {output}") build_catalog("产品图", "产品目录.pdf")

跑完之后你会得到一份 PDF 产品目录:体积约等于所有原图之和,放大看细节依然锐利,直接拿去上传平台或发客户都行。

实战二:科研论文配图的无损投递

写论文时用 matplotlib 生成的图表,如果以低质量方式转 PDF,审稿人放大一看满屏噪点就尴尬了。正确姿势是先存高清 PNG,再用 img2pdf 无损嵌入:

import matplotlib.pyplot as plt import numpy as np import img2pdf # 生成一张 300dpi 的高清折线图 x = np.linspace(0, 10, 100) plt.figure(figsize=(8, 6)) plt.plot(x, np.sin(x), label="sin(x)") plt.plot(x, np.cos(x), label="cos(x)") plt.title("实验结果对比") plt.legend() plt.savefig("chart.png", dpi=300, bbox_inches="tight") # 无损嵌入 PDF,投稿时图片依然纤毫毕现 with open("论文配图.pdf", "wb") as f: f.write(img2pdf.convert("chart.png"))

顺带一提,如果投稿要求长期归档格式,img2pdf 还支持生成 PDF/A-1b 合规文档,Python 里传pdfa="路径/到/ICC配置.icc"就行,命令行对应参数是--pdfa

新手最容易翻车的 3 个坑,提前帮你填平

每个坑我都按"症状 → 原因 → 解法"来拆,遇到对号入座即可。

坑一:JPEG 转着转着突然报错

  • 症状:命令行抛错,提示输入图片有无效的 EXIF Orientation 值。
  • 原因:某些安卓手机和佳能相机写入了方向值 0(合法范围是 1~9),img2pdf 认为图片损坏。
  • 解法:转换时加--rotation=ifvalid;或者先用exiftool -Orientation=1 图片.jpg把原图修好。

坑二:大图被工具"拒之门外"

  • 症状:转换超大尺寸图片时报DecompressionBombError之类的错误。
  • 原因:img2pdf 底层用 Pillow 读取图片元数据,而 Pillow 为了防止"解压炸弹"拒绝服务攻击,默认限制了输入图片的最大像素数。
  • 解法:确信图片来源安全时,加--pillow-limit-break关掉这道安全闸,超大图也能照样处理。

坑三:明明说无损,PDF 怎么比原图大不少?

  • 症状:转出来文件明显变大,怀疑自己用了假的无损工具。
  • 原因:能"直接搬"的只有前面表格里那几类格式。如果你输入的是带透明通道的 PNG、CMYK 图等,img2pdf 必须先转换像素数据再压缩,体积变大是预期行为,不是 bug。
  • 解法:追求最小体积时优先选用可直嵌的格式作为输入;遇到必须处理的 CMYK 图,接受它会更"胖"一点的事实即可。

动手吧:装一次、跑一遍、再往深处挖

到这里,img2pdf 的核心玩法你已经全部掌握了。剩下的事情很简单:打开终端,pip3 install img2pdf,拿你手头最常处理的那批图片转一份试试。命令行用户随时可以用img2pdf --help查看全部参数;不习惯命令行的朋友,也可以运行img2pdf --gui打开它的实验性图形界面,点选图片直接保存 PDF。

想深入了解,项目源码和文档都是现成的教材:主文档看 README.md,版本演进看 CHANGES.rst,核心实现全部在 src/img2pdf.py,项目自带的测试图在 src/tests/input/,测试用例则在 src/tests/img2pdf_test.py——从这些文件里你能看到它对几十种格式的细致处理。

如果你在阅读源码时发现了 bug 或想到了新功能,也可以提交反馈,让它变得更好用。图片转PDF 这件事,真的可以又快、又小、又不损画质——现在就动手试试吧。

【免费下载链接】img2pdfmirror of https://gitlab.mister-muffin.de/josch/img2pdf for Travis and appveyor CI项目地址: https://gitcode.com/gh_mirrors/im/img2pdf

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

← 返回列表