ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

PyMuPDF Archive 类实战指南:用统一归档树管理字体、图片与文档资源

PyMuPDF Archive 类实战指南:用统一归档树管理字体、图片与文档资源 图像处理【免费下载链接】PyMuPDFPyMuPDF is a high performance Python library for data extraction, analysis, conversion manipulation of PDF (and other) documents.项目地址https://gitcode.com/gh_mirrors/py/PyMuPDF点击查看免费下载PyMuPDFpymupdf从 v1.21.0 起提供了Archive类它把文件夹、ZIP/TAR 压缩包、内存二进制数据与另一个 Archive 统一抽象成一棵虚拟资源树让上层功能可以像访问一个超大文件夹一样按名字检索资源。本文基于仓库中的 Archive 类官方文档 与 Python 实现源码完整讲解 Archive 的构造、增删查读四大 API、path挂载点语义与重复条目处理并结合Story渲染、Document.open资源目录与字体注入等真实场景给出可复制运行的实战代码。Archive 是什么把异构资源统一成一张树Archive表示的是文件文件夹与容器文件如 ZIP、TAR的泛化。它允许你像访问一棵层次化文件夹树一样访问任意组合的本地文件夹及其中所有子文件夹ZIP / TAR 归档文件单个二进制数据块bytes、bytearray、io.BytesIO、普通文件内容另一个Archive嵌套为子归档。在 PyMuPDF 中Archive 目前只有两个消费方见 archive-class.rstStory对象渲染 HTML/文本到 PDF 时用它作为图片和字体的来源打开文档时的可选参数Document.open(..., archive...)用于指定在何处查找字体、图片等资源。因此理解 Archive 是掌握 PyMuPDF 资源注入能力尤其是Story排版与文档转换的前置基础。API 总览方法 / 属性说明Archive.add(content [, path])向归档追加新的子归档Archive.has_entry(name)检查给定名称是否是归档成员Archive.read_entry(name)读取给定名称对应的数据Archive.entry_listlist[dict]描述归档中的各项子归档构造一个 ArchiveArchive.__init__(self [, content [, path]])不传任何参数时创建一个空归档。content参数的五种形态content可以取以下任意一种每种都会以子归档sub-archive的身份挂入新建的归档另一个Archive作为子归档挂入。可视为归档嵌套。一个字符串必须是本地文件夹或文件的路径名pathlib.Path对象同样支持。文件夹会被转换为子归档其下文件及子文件夹可用名字直接访问文件将以rb模式读取二进制内容被当作单成员子归档。此时path参数必须给出作为该条目的检索名。zipfile.ZipFile或tarfile.TarFile对象整个作为子归档加入。Python 二进制对象bytes、bytearray、io.BytesIO添加单成员子归档path参数必须给出作为该条目的检索名。二元组(data, name)添加单成员子归档成员名为name。data可以是二进制对象也可以是本地文件名此时取其二进制文件内容。需要指定path时推荐使用此格式。此外content还可以是任意 Python 序列如 list 或 tuple——这是便捷格式用来一次性组合上述多种内容。源码中对应分支见 src/init.py序列会被逐个元素递归调用self.add(item, path)。path参数虚拟挂载点path必须是字符串语义如下当content是二进制数据或文件名时path是强制的即该数据被检索时使用的名字其他情况下可选用来模拟一个文件夹名 / 挂载点子归档的成员都将挂在该名字之下。例如Archive((data, name), path)表示data将通过元素名path/name被找到。ZIP 子归档同理要取其中的成员成员名必须带path/前缀。path的主要用途是区分重名条目。重要提示重复条目如果归档中存在重名条目总是返回最后添加的那个。创建归档或add追加数据时不会做重名检查请用path参数自行规避。实战用 add 组装混合资源并查看 entry_list官方文档给出了一个典型示例把两个文件夹、一个图片文件一次性地挂到mypath之下见 archive-class.rstfrom pprint import pprint import pymupdf dir1 fitz-32 # 一个文件夹名 dir2 fitz-64 # 一个文件夹名 img (nur-ruhig.jpg, img) # 一个图片文件成员名 img members (dir1, img, dir2) # 一次追加这三种内容 arch pymupdf.Archive() arch.add(members, pathmypath) pprint(arch.entry_list)输出[{entries: [310, 37, 38, 39], fmt: dir, path: mypath}, {entries: [img], fmt: tree, path: mypath}, {entries: [310, 311, 37, 38, 39, pypy], fmt: dir, path: mypath}]entry_list是归档全部子归档的列表每项是包含三个键的字典entries该子归档中顶层条目名的列表fmt子归档格式取值为dir文件夹、zipZIP 归档、tarTAR 归档或tree单个二进制条目 / 文件内容path该子归档被添加时path参数的值。entry_list在源码中的实现非常直接它就是self._subarchives列表的属性访问器见 src/init.py。而fmt、entries的登记发生在add()内部的make_subarch()辅助函数中src/init.py值得注意的细节是连续的、挂载点相同的tree类型子归档会被合并进上一条记录entries直接扩展因此entry_list中的条目数与add调用次数并不一定一一对应。查与读has_entry 与 read_entryarch.has_entry(name) # - bool arch.read_entry(name) # - bytes未找到则抛出异常两个方法都要求传入完全限定名fully qualified name即必须包含子归档挂载时path前缀。例如上面示例中图片的实际检索名是mypath/img。has_entry(name)检查该名字在任意一个子归档中是否存在返回True/Falseread_entry(name)返回该条目的二进制数据bytes。未找到时抛出异常。从源码看二者是 MuPDF 底层能力的薄封装src/init.pydef has_entry(self, name): return mupdf.fz_has_archive_entry(self.this, name) def read_entry(self, name): buff mupdf.fz_read_archive_entry(self.this, name) return JM_BinFromBuffer(buff)而entry_list的属性实现src/init.py如下property def entry_list(self): return self._subarchives源码级原理底层调用链Archive是 MuPDF 多归档multi-archive机制在 PyMuPDF 的封装。构造时调用mupdf.fz_new_multi_archive()src/init.py随后每个子归档通过fz_mount_multi_archive挂载。根据content类型add()会分派到不同的内部挂载函数见 src/init.pycontent 类型底层调用说明文件夹字符串_add_dir→fz_open_directoryfz_mount_multi_archive把磁盘目录挂载为子归档二进制数据 / 文件_add_treeitem→fz_new_tree_archivefz_tree_archive_add_bufferfz_mount_multi_archive构造树归档并放入单个 buffer文件型 ZIP/TAR_add_ziptarfile→fz_open_zip_archive/fz_open_tar_archive从磁盘路径打开容器归档内存型 ZIP/TAR_add_ziptarmemory→fz_open_zip_archive_with_stream/fz_open_tar_archive_with_stream从BytesIO流打开容器归档另一个 Archive_add_arch→fz_mount_multi_archive直接挂载既有归档对象这也解释了entry_list的fmt字段来源dir、zip、tar、tree与上表一一对应。对zipfile.ZipFile/tarfile.TarFile对象源码还会智能判断其来源有文件名的走磁盘路径fz_open_zip_archive来自内存流的走with_stream变体见 src/init.py。场景一给 Story 注入图片与字体资源Story是把 HTML/CSS 排版为 PDF 的核心组件其archive参数story-class.rst用于加载渲染所需的图片和文本字体若省略Story 不会查找任何外部资源可能产生不完整输出。关键便利点story-class.rst任何合法的 Archive 构造参数都可以直接传给archivePyMuPDF 会临时替你构造归档因此下面两种写法等价# 显式构造 story pymupdf.Story(archivepymupdf.Archive(myfolder)) # 直接传字符串等价 story pymupdf.Story(archivemyfolder)源码印证见 src/init.pyStory.__init__会在archive不是Archive实例时自动包装一次Archive(archive)。同样Story.write_stabilized/write_stabilized_with_links两个静态方法也接受archive参数并透传给Storysrc/init.py。一个把文件夹、ZIP 与内存图片合并供给 Story 的组合示例import pymupdf, io, zipfile # 1) 先准备一个 zip内含一张图片 logo.png buf io.BytesIO() with zipfile.ZipFile(buf, w) as zf: zf.writestr(logo.png, open(logo.png, rb).read()) # 2) 组装归档磁盘文件夹 内存 zip 流 单个内存图片 arch pymupdf.Archive() arch.add(assets/fonts, pathfonts) # 字体目录 - fonts/... arch.add(zipfile.ZipFile(buf), pathimgzip) # zip 流 - imgzip/logo.png arch.add((open(bg.jpg, rb).read(), bg.jpg)) # 内存图片 - bg.jpg # 3) 交给 Story story pymupdf.Story( htmlhtmlbodyimg srcimgzip/logo.pngHello Archive/body/html, user_cssbody { font-family: myfont; }, archivearch, )场景二打开文档时指定资源查找位置从 v1.28.0 起Document.__init__/open新增了archive关键字参数document.rst作为打开文档时字体、图片等资源的来源适用于重排类文档如 HTML、EPUB或需要外部字体支持的场景doc pymupdf.open(some.html, archivepymupdf.Archive(myfolder))构造签名在源码中为Document.__init__(self, filenameNone, streamNone, filetypeNone, rectNone, width0, height0, fontsize11, archiveNone)src/init.py。在内部字符串 /pathlib.Path形式的archive会被先包装为Archive实例再通过fz_open_document_with_stream_and_dir/fz_open_document_with_stream_and_dir系列调用把归档作为资源目录交给文档对象src/init.py。场景三向归档注入字体文件pymupdf.insert_font()专门用于把字体文件放进归档供后续使用src/init.py它接收fontcode、CSS 参数与Archive必填将fontcode对应的字体缓冲区写入该归档使字体成为可检索的归档成员。这对于需要动态注册 CSS 字体的Story排版流程尤其有用。测试中的 Archive 用法仓库测试用例也直接印证了 Archive 的日常打开方式——直接以当前目录构造归档并交给 Story 渲染tests/test_story.pyarch pymupdf.Archive(.)把当前工作目录整体挂为子归档tests/test_story.pys pymupdf.Story(archivepymupdf.Archive(.))将归档直接作为 Story 资源源。这说明 Archive 的 文件夹即子归档 语义非常灵活哪怕只传一个.整个目录树都可通过相对路径名被检索。小结Archive把文件夹、ZIP/TAR、内存二进制、嵌套 Archive统一为一棵可检索的资源树path参数充当虚拟挂载点是规避重名条目的关键四大 APIadd追加子归档、has_entry判存在、read_entry取二进制数据、entry_list盘点全部子归档fmt/entries/path三字段底层完全基于 MuPDF 的 multi-archive 挂载机制fz_new_multi_archivefz_mount_multi_archivePyMuPDF 侧只做类型分派与簿记两个核心消费场景Story(archive...)渲染图片/字体、Document.open(archive...)打开文档时定位外部资源二者都支持直接传入字符串等可构造 Archive 的参数若出现重名条目检索时总是命中最后添加者创建阶段不做去重请善用path前缀。掌握 Archive 之后你可以把散落在磁盘目录、压缩包与内存中的资源统一组织起来交给 Story 和 Document 使用从而写出资源来源清晰、可复用的 PDF 生成与文档转换代码。赞分享图像处理【免费下载链接】PyMuPDFPyMuPDF is a high performance Python library for data extraction, analysis, conversion manipulation of PDF (and other) documents.项目地址https://gitcode.com/gh_mirrors/py/PyMuPDF点击查看免费下载相关推荐PyMuPDF中的Archive类详解统一管理文件与压缩包资源PyMuPDF中的Archive类详解统一管理文件与压缩包资源 还在为PDF文档处理中复杂的资源管理而头疼吗每次需要处理外部字体、图片或其他资源时都要手动图像处理Notesnook 笔记归档Archive完全指南归档、取消归档与底层实现原理Notesnook 笔记归档Archive完全指南归档、取消归档与底层实现原理 归档是 Notesnook 中整理笔记清单、保留历史内容的核心功能之一它前端移动开发桌面应用应用安全Borg 归档标签Archive Tags完全指南用 borg tag 管理、匹配与保护你的备份归档Borg 归档标签Archive Tags完全指南用 borg tag 管理、匹配与保护你的备份归档 导读 本文聚焦 Borg 备份工具的归档标签arc运维存储上一篇终极指南Moody项目地理定位集成 - 在Core Data中高效存储和管理位置数据下一篇FreeCAD CAM 工作台统一语言词汇表解读 ADR-000 领域术语规范创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表