# pdftool **Repository Path**: yhditto/pdftool ## Basic Information - **Project Name**: pdftool - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-07-29 - **Last Updated**: 2026-08-07 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # PDF标签处理工具 (PDF Label Tool) > 将任意尺寸PDF转换为标准100×100mm标签,支持高清输出、线条加粗、文本编辑、图片替换,专为300DPI打印优化。 ## 功能概览 | 功能 | 说明 | |------|------| | 尺寸调整 | 任意尺寸PDF → 100×100mm(可选80/50mm),无白边 | | DPI调节 | 72-1200DPI可调,高清模式下DPI直接决定输出分辨率 | | 线条加粗 | 区域分割线加粗,确保打印识别,无重影 | | 高清输出 | 混合增强:按输出像素重采样+分级锐化+背景清理+线条加粗 | | 文本编辑 | 识别文本块,保留原始字体/字号/颜色,支持就地双击编辑 | | 文本拖动 | 鼠标拖动文本块改位置,锚点认领防止误移邻块 | | 文本缩放 | 拖角标改变文本区域大小,按新区域自动重排 | | 撤销/重做 | Ctrl+Z撤销 / Ctrl+Y重做,最多20步内存字节快照 | | 图片替换 | 双击替换图片,自动匹配原尺寸比例,支持ICC安全加载 | | 图片操作 | 鼠标拖动移动、方向键微调(1pt/次)、+/-键缩放(1.1倍/次) | | CMYK零损失 | 直取原始图片流,CMYK/灰度图无色彩转换损失 | | 扫描件识别 | 自动检测扫描件,切换等比缩放防止变形 | | 智能路径 | 自动检测矢量/高清图/低清扫描/图片为主,选择最优处理路径 | ## 快速开始 ### 环境要求 - Python 3.10+ - Windows 10/11(EXE已打包,无需Python环境) ### 依赖安装 ```bash pip install PyMuPDF numpy opencv-python Pillow PyQt5 ``` ### 运行源码 ```bash cd pdf_tool python main.py ``` ### 使用EXE 直接运行 `dist/PDF_Label_Tool/PDF_Label_Tool.exe`,无需安装任何依赖。 ## 使用指南 ### 四步操作流程 ``` STEP 1 选择PDF文件 → STEP 2 设置参数 → STEP 3 处理/预览 → STEP 4 保存 ``` ### 快捷键 | 快捷键 | 功能 | |--------|------| | Ctrl+Z | 撤销上一步编辑(最多20步) | | Ctrl+Y / Ctrl+Shift+Z | 重做最后一次撤销 | | Ctrl+Enter | 就地文本编辑提交 | | Esc | 取消就地编辑 | | 方向键 | 选中图片后微调位置(1pt/次) | | + / = | 选中图片后放大(1.1倍) | | - | 选中图片后缩小(0.9倍) | ### 参数说明 | 参数 | 选项 | 说明 | |------|------|------| | 目标尺寸 | 100×100 / 80×80 / 50×50 mm | 输出标签尺寸 | | DPI | 72-1200 | 矢量模式无效;高清模式决定位图分辨率 | | 线条粗细 | 0.0-5.0 pt | 加粗所有低于此值的线条,0.3以下不处理 | | 缩放模式 | 直接缩放/智能/无白边填充/等比适合/填充宽度/填充高度 | 见下表 | | 高清输出 | 勾选/不勾选 | 勾选后DPI生效,启用图像增强管线 | ### 缩放模式详解 | 模式 | 适用场景 | 行为 | |------|----------|------| | 直接缩放 | 矢量PDF(默认) | 拉伸填充至目标尺寸,不裁切不变形 | | 智能模式 | 通用 | 接近正方形时填充,差异大时等比 | | 无白边填充 | 需要填满 | 最大缩放填充,可能裁切边缘 | | 等比适合 | 扫描件 | 等比缩放,可能有白边但不变形 | | 填充宽度 | 宽度优先 | 宽度填满,高度自适应 | | 填充高度 | 高度优先 | 高度填满,宽度自适应 | > 扫描件自动切换为「等比适合」模式,防止图片变形。 ### 文本编辑与移动 1. 加载PDF后,预览区自动识别所有文本块并显示蓝色高亮框 2. **就地编辑**:双击预览中的文本,弹出编辑框输入新内容,Ctrl+Enter提交 3. **拖动移动**:鼠标拖动文本块到新位置,松手后自动重排 4. **区域缩放**:拖动文本框角标改变区域大小,内容按新区域重新排版 5. 编辑保留原始字体、字号、颜色(多span样式精确还原) 6. 支持中文(自动映射SimHei/SimSong等字体) > 文本移动采用**锚点认领**机制:首次移动登记锚点,之后只认自己的锚点,拖动时不会误吸邻块内容。 ### 图片操作 | 操作 | 方式 | |------|------| | 替换图片 | 双击图片,或选中后点「替换高清图」按钮 | | 移动图片 | 鼠标拖动预览中橙色框 | | 微调位置 | 选中图片后按方向键(1pt/次) | | 缩放图片 | 选中图片后按+/=键放大(1.1倍),-键缩小(0.9倍) | **图片替换特性**: - 自动匹配原图尺寸比例(白色padding补齐) - 显式移除ICC色彩配置文件,避免`code=8: invalid ICC colorspace`错误 - 使用`page.replace_image`直接替换,不破坏内容流,无黑底 - 替换后保持xref不变,元素索引稳定 ## 项目结构 ``` pdf_tool/ ├── main.py # 入口文件(内嵌字体加载) ├── pdf_engine.py # PDF核心引擎(智能路由/缩放/线条加粗) ├── image_enhancer.py # 纯图片型PDF增强(全页面降噪/背景/锐化) ├── mixed_enhancer.py # 混合PDF图片增强(按输出像素重采样/分级锐化) ├── image_manager.py # 图片管理(提取/替换/移动/缩放/文本编辑) ├── element_manager.py # 元素识别(文本块拆分+图片元素+多样式快照) ├── ui_main_window.py # 主窗口(面板管理/处理调度/撤销重做) ├── ui_control_panel.py # 控制面板(参数设置/文件选择/撤销按钮) ├── ui_preview.py # 预览组件(缩放/高亮/拖动/键盘/就地编辑) ├── ui_styles.py # UI样式(工程蓝图风格) ├── log_config.py # 日志配置(文件+控制台) ├── build_exe.py # PyInstaller打包脚本 ├── assets/ # 内嵌资源 │ ├── fonts/ # 字体文件(Inter/JetBrainsMono,打包后保证可用) │ ├── logo.ico # 应用图标 │ └── logo.png # 应用Logo ├── README.md # 本文档 └── dist/ # 打包输出 └── PDF_Label_Tool/ └── PDF_Label_Tool.exe ``` ## 技术架构 ### 核心依赖 | 库 | 用途 | |----|------| | PyMuPDF (fitz) | PDF读写、页面渲染、图片操作、文本提取 | | OpenCV (cv2) | 图像处理(降噪/阈值/形态学/锐化/双峰度检测) | | NumPy | 像素级内容边界检测、数组运算 | | Pillow (PIL) | 图片加载、ICC处理、比例适配 | | PyQt5 | GUI界面(三栏可拖拽布局) | ### 智能处理路由 ``` 输入PDF → 内容类型检测 │ ├─ 纯图片型PDF(扫描件) / 图片占比>55% │ └─ 全页面图像增强路径(image_enhancer) │ ├─ DPI渲染位图 │ ├─ 中值滤波 │ ├─ 保护Mask构建(线条+文字) │ ├─ 背景清理 │ ├─ 线条加粗 │ └─ 锐化输出 │ └─ 可编辑PDF(矢量文字+图片) └─ 矢量路径(mixed_enhancer增强图片) ├─ show_pdf_page缩放(文字保持矢量不栅格化) ├─ 图片按输出实际像素重采样 ├─ 双峰度分级锐化(线稿/照片不同力度) ├─ 矢量draw_line加粗线条 └─ 重绘编辑文本 ``` ### 混合PDF图片增强管线 针对「矢量文字+图片」的混合型PDF,**文字永远保持矢量形式不栅格化**,仅对图片做增强: 1. **CMYK零损失加载**:优先直取原始图片流(`fitz.Pixmap(doc, xref)`),CMYK/灰度图不经过页面渲染,避免色彩转换损失 2. **缩放后DPI计算**:按显示尺寸×缩放比×目标DPI计算输出实际像素,确保增强在最终分辨率上进行 3. **双峰度判断内容类型**:灰度直方图两端占比,>0.70视为线稿/条码/二维码,<0.55视为照片 4. **分级锐化**: - 纯黑白(>0.95):跳过锐化(已无软边,锐化只会压出灰边) - 线稿(≥0.75):强锐化 σ=1.2 amt=0.95 - 混合(≥0.55):中锐化 σ=1.0 amt=0.80 - 照片(<0.55):轻锐化 σ=0.8 amt=0.60 5. **线稿不下采样**:线稿/条码/二维码保留原始像素,避免黑白模块被重采样平均成灰糊 6. **透明通道跳过**:带SMask的图片跳过增强,避免写回丢失透明度 7. **JPEG智能回写**:原图是JPEG的走高质量JPEG(quality=98)回写,避免无损位图让文件膨胀 ### 关键技术点 **无白边缩放**:`direct`模式分别计算X/Y缩放比,拉伸填充整页,不做内容裁切。 **无重影加粗**:用矢量`draw_line`直接画粗线覆盖原细线,不依赖redaction(Form XObject不支持),避免重叠残影。 **ICC安全加载**:用Pillow打开图片→`convert('RGB')`→`info.pop('icc_profile')`→存临时PNG→`fitz.Pixmap`加载,彻底避免色彩空间错误。 **黑底消除**:移动/缩放图片时传`for_display=False`保留alpha通道,透明区域不合成白底也不产生黑块;任何fitz颜色转换失败时用Pillow直接读xref stream保留RGBA。 **内存字节快照撤销**:每次编辑前把`_src_doc`序列化为内存字节(`tobytes(garbage=0, deflate=False)`)压入栈,撤销/重做时从字节重建文档,最多20步。新编辑清空重做栈(线性历史)。 **锚点认领防误移**:文本块首次移动登记锚点坐标,之后只认自己登记的锚点。当区域压到冻结区域头上时不会把邻块内容吸走,避免连续拖动带跑邻块。 **临时文件保块号稳定**:保存中间状态用`garbage=0 clean=False deflate=True`,不回收xref不重编号、不重组内容流,保证UI持有的block_no/xref绝对位置稳定。 **保护Mask**:形态学检测水平/垂直线条+文字区域,背景清理仅作用于非保护区域,确保区域边线不丢失。 ## 打包EXE ```bash python build_exe.py ``` 输出路径:`dist/PDF_Label_Tool/PDF_Label_Tool.exe` 打包特性: - `--onedir` 模式,启动速度快 - 排除matplotlib/pandas/scipy等无用大库 - 显式包含fitz/numpy/cv2/PIL所有二进制 - `--add-data assets;assets` 打包内嵌字体和图标 - 日志输出到EXE同级`pdf_tool.log` ## 日志排查 EXE运行日志位于程序同级目录:`pdf_tool.log` 日志格式: ``` HH:MM:SS [LEVEL] module:line - message ``` 常见问题排查: | 问题 | 排查方向 | |------|----------| | 图片替换报错 | 查看img_mgr日志,检查ICC处理流程 | | 处理后模糊 | 确认PDF类型(矢量/扫描件),检查是否走了增强路径 | | 线条加粗无效 | 检查line_width参数是否>0.3,查看是否为hairline(0宽度) | | 黑底/黑框 | 查看img_mgr日志,确认for_display=False及alpha保留流程 | | 撤销无效 | 查看main_win日志的Undo栈状态,确认快照是否压入成功 | | 文本拖动带跑邻块 | 查看锚点认领日志,确认other_anchors排除逻辑 | ## 版本历史 | 版本 | 关键改进 | |------|----------| | v11 | 撤销/重做系统(Ctrl+Z/Y);文本拖动移动+锚点认领;文本区域缩放重排;就地双击编辑;混合PDF分级锐化;CMYK零损失直取;内嵌字体打包 | | v10 | 矢量路径优先;检测矢量/高清图内容,仅对纯低清扫描件做图像增强 | | v9 | 保护Mask机制;线条+文字区域保护,背景清理不影响边线 | | v8 | 降噪参数优化;NLM h=7,移除双边滤波,减少涂抹感 | | v7 | 图像级线条加粗;先渲染DPI再检测加粗,避免模糊 | | v6 | 高清输出统一;移除超分辨率重绘,聚焦降噪/背景/锐化 | ## 许可证 内部工具,仅供团队使用。