PyMuPDF无法直接提取矢量图形,因其仅支持光栅化导出;page.get_images()仅返回嵌入位图,而矢量内容需通过page.get_drawings()解析绘图指令获取近似路径描述。

PyMuPDF 本身不直接提取矢量图形(如 PDF 中的路径、贝塞尔曲线、文本轮廓等),它只能导出光栅化后的图像——也就是说,你拿到的是 PNG/JPEG,不是 SVG 或原始路径数据。
为什么 page.get_images() 拿不到矢量图
PDF 中的“图片”通常指嵌入的位图(JPEG、PNG、JBIG2 等),它们在 page.get_images() 返回结果里;而矢量内容(线条、矩形、文字、路径)是通过绘图指令(q、cm、re、f、Do 等操作符)动态绘制的,不属于“图像对象”。get_images() 完全忽略这些。
- 调用
page.get_images()后返回空列表,不代表页面没图,很可能只是没嵌入位图 - 矢量图常以
Form XObject或直接内联路径形式存在,需解析页面内容流(page.read_contents())或使用page.get_drawings() -
page.get_drawings()是目前最接近“提取矢量结构”的接口,但它返回的是近似路径描述(含坐标、颜色、线宽、填充标志),不是可编辑的 SVG DOM
用 page.get_drawings() 获取近似矢量路径
这个方法会解析页面内容流,把绘图指令聚合成路径(paths)、矩形(rects)、文本块(texts)等结构,是目前 PyMuPDF 中唯一能触及矢量逻辑的入口。
Python 编程规范与最佳实践。强制 PEP 8 代码风格、语法校验、单元测试执行,适用于代码编写、审查和重构。触发词:Python、代码规范、py_compile、单元测试。
- 启用条件:PyMuPDF ≥ 1.19.0,且 PDF 不加密(或已解密)
- 返回值是字典列表,每个字典含
"items"(路径点序列)、"fill"(是否填充)、"stroke"(是否描边)、"color"、"fill_color"等字段 - 注意:
"items"中的点是相对于页面左下角的 PDF 坐标(y 轴向上),导出为 SVG 时需翻转 y 值 - 不支持贝塞尔曲线的高保真还原(部分高阶曲线会被折线近似)
drawings = page.get_drawings()
for d in drawings:
if d["items"] and d.get("fill", False):
# 这可能是填充的矢量区域,比如 logo 轮廓
print("Fill path with", len(d["items"]), "points")
导出为 SVG 的实际限制与替代方案
PyMuPDF 不提供 page.to_svg() 或类似方法。若你真正需要 SVG 输出,得自己基于 get_drawings() 构建:
- 手动遍历
drawings,将每条路径转成,注意处理moveTo/lineTo/curveTo映射 - 忽略 PDF 中的渐变、透明度混合、剪切路径(
clip),这些在get_drawings()中无对应字段 - 文字通常不会出现在
get_drawings()中——它们走的是文本提取路径(page.get_text("dict")),且默认是轮廓转路径(textpage = page.get_textpage(); textpage.extractDICT()不行,得用page.get_text("rawdict")+page.get_cdrawings()配合) - 更可靠的做法是换工具:用
pdf2svg(命令行)、poppler-utils的pdf2cairo -s 1 -ps,或 Python 绑定fitz.Page.get_svg_image()(仅限 MuPDF 1.23+ 且 PyMuPDF 编译时启用了 SVG 后端,极少见)
真正想提取矢量图形时,别依赖 get_images();get_drawings() 是唯一可用的钩子,但它输出的是“绘图意图”的简化快照,不是原始矢量源。如果你看到 PDF 里有个清晰的 Logo 却导不出 SVG,大概率是因为它被画成了路径而非嵌入图片——这时候你要的不是“提取图片”,而是“逆向绘图指令”。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










