Skip to main content

atlisp-pdf2dwg

把 PDF 图纸/文档转换为可编辑的 DXF(可选 DWG)。

流程:OCR 图文混排 → 原生 PDF 矢量提取 + 位图矢量化 → ezdxf 组装 DXF。

  • OCR 图文混排:默认为本地 RapidOCR(PP-OCR,逐行坐标、CPU、快);可选 surya VLM (整页布局 + 文本,精度高但重)。
  • 原生矢量:若 PDF 仍是矢量(含被转曲的文字),直接提取线条,比追踪位图更清晰、更小; 文字块内的字形轮廓会被剔除并替换为真实文字实体。
  • 位图矢量化:PDF 内嵌图片先做中值分割颜色量化,再用 potrace 拟合平滑贝塞尔曲线 (回退到 OpenCV 轮廓追踪),随后采样+简化多边形,按原始变换/旋转映射回图纸并裁剪到页面。 相同图片(页眉 logo、二维码等)跨页只追踪一次,并可多进程并行,质量与速度兼顾。
  • 默认输出线条(LWPOLYLINE),不用 HATCH。这是实测决定的:同一张图经 LibreDWG 转 DWG, HATCH 版报 249 条 Skip HATCH common handles 告警(填充大面积丢失),线条版只有 1 条。 代价是墨迹召回 84.2% → 68.3%(平铺多段线依赖绘制顺序,HATCH 则是逐环奇偶填充)。 若 DXF 是最终交付、且更在意洞的正确性,可加 --vector-mode rings 改用 HATCH。
  • 页面堆叠:多页 PDF 默认纵向堆叠到模型空间,页间留间距;可用 --flat 关闭。

安装

pip install atlisp-pdf2dwg     # 核心(矢量 + OpenCV 位图,不含 OCR)
pip install "atlisp-pdf2dwg[potrace]"  # + potrace 曲线追踪(推荐,图片更精细)
pip install "atlisp-pdf2dwg[rapid]"    # + RapidOCR(推荐的本地 OCR)
pip install "atlisp-pdf2dwg[all]"      # rapid + potrace
pip install "atlisp-pdf2dwg[surya]"    # + surya VLM(可选,重)

需要 DWG 输出时另装 GNU LibreDWG 的 dxf2dwg, 或设置环境变量 PDF2DWG_DXF2DWG=/path/to/dxf2dwg。

命令行

# 默认:RapidOCR + 矢量 + 位图,输出 DXF
pdf2dwg convert 图纸.pdf -o 图纸.dxf

# 指定页码、DPI、关闭位图矢量化
pdf2dwg convert 图纸.pdf --pages 1-5,8 --dpi 300 --no-images

# 只提取矢量+位图(不 OCR,文字保留为轮廓)
pdf2dwg convert 图纸.pdf --no-ocr

# 输出 DWG(需 dxf2dwg)
pdf2dwg convert 图纸.pdf --format dwg

# 复用/缓存 OCR 结果
pdf2dwg convert 图纸.pdf --ocr-cache .ocr_cache

# 图片追踪质量/性能
pdf2dwg convert 图纸.pdf --trace potrace --image-max-dim 1600 --image-colors 8 --jobs 8
pdf2dwg convert 图纸.pdf --trace opencv        # 不装 potrace 时的回退
pdf2dwg convert 图纸.pdf --image-min-area 8 --image-max-polys 20000   # 压体积

# 其它子命令
pdf2dwg ocr 图纸.pdf -o ocr_json --engine rapid
pdf2dwg render 图纸.dxf -o preview.png --scale 1.5
pdf2dwg to-dwg 图纸.dxf
pdf2dwg info                 # 查看引擎与 dxf2dwg 路径

Python API

from pdf2dwg import convert_pdf

convert_pdf(
    "图纸.pdf",
    "图纸.dxf",
    page_spec="1-10",      # 1-based;或 pages=[0,1,2]
    dpi=200,
    ocr="rapid",           # 或 "surya" / None
    images=True,           # 位图矢量化
    vectors=True,          # 原生 PDF 矢量
    stack=True,            # 多页纵向堆叠
    ocr_cache=".ocr_cache",
)

分步使用:

import pymupdf
from pdf2dwg import get_engine, build_dxf, render_page

doc = pymupdf.open("图纸.pdf")
engine = get_engine("rapid")
pages_ocr = {i: engine.run_image(render_page(doc, i, 200), i + 1, 200)
             for i in range(doc.page_count)}
build_dxf("图纸.pdf", "图纸.dxf", pages_ocr=pages_ocr)

输出图层

图层 内容
TEXT / TEXT-TITLE OCR 文字(正文 / 标题),样式 HZ(默认 simsun.ttc)
GRAPHICS / GRAPHICS-FILL PDF 原生矢量(描边 / 填充),真彩色
IMAGES 位图矢量化结果(真彩色)
PAGE 页面边框与页码

说明

  • 坐标单位与 PDF 一致(points,1 pt = 1/72 inch)。

  • 输出为 R2004 DXF:更早的版本无法写出真彩色(420 组码),颜色会全部丢失。

  • 默认 --vector-mode rings(HATCH 带洞);legacy 用平铺 LWPOLYLINE,洞靠绘制顺序 用背景色多边形遮挡,重叠时可能出错。

  • 中文文字样式默认字体 simsun.ttc,可在 build_dxf(..., text_font=...) 中修改; 若 CAD 中字体缺失,替换为本地已安装的中文字体即可。

  • 位图矢量化对线条图效果最佳;照片类图片会产生较多多边形,可用 --image-min-area / --image-max-polys / --no-images 控制。

  • 灰阶抗锯齿归并(默认开启,merge_neutral):~200 DPI 扫描件里的 0.25 pt 线只有一个 抗锯齿像素,一条黑线会散成 (121,121,121)…(216,216,216) 一整条灰阶,每一级都变成独立的 填充,最浅那级在白纸上基本看不见。现���把严格中性灰(max-min ≤ 12)归并到最深的一档, 并合并标签消除重复环。只处理中性灰是有意为之:封面的米色 (200,197,185) 通道差为 15、 蓝色 logo 根本不是中性色,都会被保留。实测墨迹召回 70.1% → 82.0%,实体数 −19.8%。 用 vectorize_image(..., merge_neutral=False) 可关闭。

  • 合并后的中性灰掩膜再做 3×3 形态学闭运算(neutral_close,默认 3)。合并会交错灰阶各级,掩膜边界呈阶梯状,产生大量冗余环。只对这一个标签做闭运算即可:9 页实测召回 82.0% → 84.2%,IoU 0.482 → 0.487,实体数 −9.4%,体积 −8.0%(第 5 页 2.18 → 1.59 MB)。注意闭运算会让笔画略微变粗,rgb_mae 会上升。

  • --image-max-dim(默认 600)是体积与保真的主要开关。绝大多数内嵌图实际放置尺寸 远小于其像素尺寸,600 已足够;只有当某页把扫描图放大显示时(如 2500px 的图放到 700pt 宽)才需要调到 1000~1600,否则细线会丢。

  • 质量度量工具。ink_iou / pct_bad_px 是灰度的,对颜色完全失明——把整张图压成 单一墨色也能拿高 IoU。所以务必同时看 ink_colour_acc 与 rgb_mae:

    python tools/compare_modes.py 图纸.pdf --pages 1-5 --dpi 100   # legacy vs rings
    python tools/auto_tune.py    图纸.pdf --pages 1-61              # 逐文档评估追踪参数
    
  • --auto-tune N(实验性)会抽样 N 页评估追踪参数并采纳胜出者。它只在超过保守阈值时 才改变配置;在参考图纸上它的建议在未抽样页上反而更差(颜色 −1.2 点、实体 +4.6%, 仅换 +0.005 IoU),因此默认值被保留。建议先用 tools/auto_tune.py 诊断再决定。

开发

pip install -e ".[dev,rapid]"
pytest
ruff check src tests tools    # 硬闸门:只查真 bug
python -m build

许可

MIT

Metadata

Release files for atlisp-pdf2dwg 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for atlisp-pdf2dwg 0.1.0
File Size Uploaded
atlisp_pdf2dwg-0.1.0.tar.gz 67.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for atlisp-pdf2dwg 0.1.0
File Interpreter ABI Platform
atlisp_pdf2dwg-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 116.8 kB

Release files / atlisp_pdf2dwg-0.1.0.tar.gz

Download URL atlisp_pdf2dwg-0.1.0.tar.gz
Size 67.1 kB
Tags Source
SHA-256 checksum
How to use checksums
cc4f654e0b2ad5fe30f93862bb7f5280d3a5db52439353568fb9987ab0879405
BLAKE2b-256 checksum
How to use checksums
d80d45e7cf2f9f1d6e5e1116f552f56d2927e600617dbcaa267e4217f7446f40
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.7

Release files / atlisp_pdf2dwg-0.1.0-py3-none-any.whl

Download URL atlisp_pdf2dwg-0.1.0-py3-none-any.whl
Size 49.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
29107ab093f2d8f605d66624275960cf900f931e5e5cfe22017fe50f7376e9ce
BLAKE2b-256 checksum
How to use checksums
26994d67dea9c038fa590aebc32f357bf15c871361d5ee0b9374eea98dbe53e4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.7

Release history Release notifications | RSS feed

0.1.2

2 release files

0.1.1

2 release files

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page