cad2image · 让 CAD 图纸渲染告别残余杂线
cad2image 是一个把 DWG / DXF 图纸渲染成 PNG / SVG 的命令行工具与 Python 库。它用「ODA File Converter + ezdxf」重建渲染管线,替换 Acme CAD Converter,并消除其底层 GDI 栅格化产生的「残余杂线」——圆弧走真圆弧,无多边形折痕与毛须。
核心功能
- 高保真渲染:DWG/DXF → PNG(任意 DPI)或 SVG(矢量),圆弧渲染为真圆弧。
- 告别残余杂线:替换 Acme 的 GDI 栅格化路径,无毛须、无折痕。
- 中文开箱即用:内置开源中文字体,自动替换图纸里引用的 SimSun / 宋体等专有字体。
- 完整打印样式:支持 CTB 打印样式表、线宽控制、颜色 / 灰度 / 单色输出。
- 批量处理:目录递归处理,逐条报告成功/失败,不因单个失败中断整批。
- 双形态:既可用作命令行工具,也可作为 Python 库嵌入。
安装
要求 Python 3.8+。
# 从 PyPI 安装(推荐)
pip install cad2image
将 DWG 转为 DXF 需要另外安装免费的 ODA File Converter(https://www.opendesign.com/guestfiles/oda_file_converter)。若只渲染已有的 DXF,则无需安装。
ODA 可执行文件路径解析优先级:
- 环境变量
ODA_FILE_CONVERTER_PATH - 默认路径
D:\ODA\ODAFileConverter_title 21.5.0\ODAFileConverter.exe
快速开始
安装后,使用控制台命令 cad2image(也可用 python -m cad2image):
# 单个 DWG → PNG(默认 300 DPI)
cad2image 轴套.dwg -o 轴套.png
# 高清 PNG
cad2image 轴套.dwg -o 轴套.png --dpi 1200
# DWG → SVG(矢量)
cad2image 轴套.dwg -o 轴套.svg
# 直接渲染已有的 DXF(跳过 ODA)
cad2image 轴套.dxf -o 轴套.png
# 批量处理目录(递归子目录)
cad2image "CAD Test/" -o out/ --recursive
常用场景
# 白底 / 黑底 / 透明底
cad2image 图.dwg -o 图.png --background white
cad2image 图.dwg -o 图.png --background black
cad2image 图.dwg -o 图.png --background off
# 应用 CTB 打印样式表(如黑白线型)
cad2image 图.dwg -o 图.png --ctb 黑白线型.ctb
# 按内容自适应页面,四周留 5% 余量
cad2image 图.dxf -o 图.png --fit --margin 5.0
# 单色 / 灰度输出
cad2image 图.dwg -o 图.png --color monochrome
cad2image 图.dwg -o 图.png --color grayscale
# 指定页面尺寸(mm)
cad2image 图.dwg -o 图.png --width 420 --height 297
命令行参数
| 参数 | 说明 | 默认 |
|---|---|---|
--output, -o |
输出文件/目录 | 与输入同目录 |
--dpi |
PNG 分辨率 | 300 |
--format, -f |
输出格式 png / svg |
png |
--background |
default / white / black / off |
white |
--color |
color / monochrome / grayscale / black / white |
color |
--lineweight |
absolute / relative |
absolute |
--lineweight-scaling |
线宽整体缩放系数(仅绝对线宽生效) | 1.0 |
--min-lineweight |
最小打印线宽(mm) | 无 |
--relative-max-stroke-width |
相对线宽:最粗线宽占页面较小边比例 | 0.001(0.1%) |
--relative-min-stroke-width |
相对线宽:最细线宽占最粗线宽比例 | 0.05(5%) |
--ctb |
CTB 打印样式表路径 | 无 |
--font-dir |
附加字体目录(SHX / TTF / OTF) | 无 |
--layout |
布局名(缺省模型空间) | 模型空间 |
--width / --height |
页面尺寸(mm) | 自适应 |
--fit |
按内容包围盒自适应页面 | False |
--margin |
内容自适应页面时的四周余量(%,相对内容较小边) | 3.0 |
--recursive |
目录批量时递归子目录 | False |
--oda-path |
ODA 可执行文件路径 | 环境变量/默认路径 |
退出码:0 成功;1 转换或渲染失败(批量时存在任一失败即非零)。
从 Acme CAD Converter 迁移
| Acme 参数 | 本工具映射 |
|---|---|
/res N |
--dpi N |
/w /h(mm) |
--width / --height |
/e /ad(缩放扩展) |
--fit(包围盒自适应) |
/b 背景色 |
--background |
/lw 0/1/2 |
--lineweight + --lineweight-scaling |
/p 1/2/3(1bit/灰度/256色) |
--color(灰度暂以 monochrome 近似,待 Phase 2) |
/pw myset |
plotstyle.load_ctb(尚未实现,见已知限制) |
/a 0/-1/-2(布局选择) |
--layout |
/l 报告 |
批处理汇总 + 退出码 |
字体与中文
中文与 ASCII 标注开箱即用——包内已内置开源字体(SIL OFL 1.1),无需额外配置:
| 字体文件 | 用途 |
|---|---|
SourceHanSerifSC-Regular.ttf |
中文(含拉丁字符) |
NotoSansMono-Regular.ttf |
ASCII 等宽,近似 CAD 单线字体 |
CAD 图纸常引用专有字体(微软 SimSun/NSimSun、Autodesk romans.shx/txt.shx 等),渲染时会自动重写为内置开源字体:
SimSun/NSimSun/宋体/ 中文 bigfont →SourceHanSerifSC-Regular.ttf- 其余 SHX 字形字体 →
NotoSansMono-Regular.ttf
替换会改变文字外观,但保证纯开源、无再分发风险。若需严格保留原字体观感,可自行将对应字体放入
fonts/,或用--font-dir指定附加字体目录。
完整许可与署名见 src/cad2image/fonts/OFL.txt 与 NOTICE。
已知限制
- 灰度输出(Acme
/p 2):暂以 monochrome 近似,真正的 256 级灰度需像素级后处理。 - 3D 消隐(Acme
/hide):未实现,假设输入为 2D 工程图。 - Xref 外部引用:转换前需确保 xref 文件与主图同目录(与 Acme 行为一致)。
- 页面单位:模型空间包围盒自适应时假定绘图单位为 mm(
$INSUNITS未做换算)。 - SHX 中文 bigfont:ezdxf 1.1.x 不支持 bigfont 中文大字体,引用这类字体的图纸会被自动重写为 Noto Sans SC(见「字体与中文」)。
License
开发者指南
Python API
除 CLI 外,也可作为 Python 库导入,提供三层能力:渲染(DXF→PNG/SVG)、转换(DWG→DXF)、批处理。仅 DWG→DXF 转换需要 ODA File Converter,纯 DXF 渲染不需要。
from cad2image import RenderOptions, render_dxf, process_dwg, process_directory
# 渲染 DXF → PNG/SVG(按输出扩展名自动选后端)
render_dxf("轴套.dxf", "轴套.png", RenderOptions(dpi=300))
render_dxf("轴套.dxf", "轴套.svg", RenderOptions())
# DWG → 图片(端到端)
out = process_dwg("轴套.dwg", "out/", RenderOptions(dpi=600)) # 返回 Path
# 分步转换(先转 DXF 再渲染,便于缓存)
from cad2image import convert_dwg_to_dxf, render_to_svg
dxf = convert_dwg_to_dxf("轴套.dwg", "dxf_cache/")
render_to_svg(dxf, "轴套.svg", RenderOptions())
# 批量处理目录
result = process_directory("CAD Test/", "out/", RenderOptions(),
output_format="png", recursive=True)
print(f"成功 {result.success_count},失败 {result.failure_count}")
# CTB 打印样式
from cad2image import load_ctb, get_lineweight
styles = load_ctb("黑白线型.ctb")
lw = get_lineweight(styles, aci=1) # 颜色索引 1 的线宽(mm),未覆盖时为 None
render_dxf("图.dxf", "图.png", RenderOptions(ctb="黑白线型.ctb"))
RenderOptions 常用参数:
RenderOptions(
dpi=300, # PNG 分辨率
background="white", # default/white/black/off
color_policy="color", # color/monochrome/grayscale/black/white
lineweight_policy="absolute", # absolute/relative
lineweight_scaling=1.0, # 线宽整体缩放(仅绝对线宽)
min_lineweight=None, # 最小打印线宽(mm)
relative_max_stroke_width=0.001, # 相对线宽最粗比例
relative_min_stroke_width=0.05, # 相对线宽最细比例
ctb="", # CTB 样式表路径
font_dir="", # 附加字体目录(SHX/TTF/OTF)
layout_name=None, # 布局名,None=模型空间
width_mm=None, height_mm=None, # 显式页面尺寸(mm)
fit_to_extents=False, # 按内容包围盒自适应
margin=3.0, # 自适应时四周余量(%)
)
错误统一抛 FileNotFoundError / ValueError / RuntimeError,可放心捕获。
项目结构
src/cad2image/
├── cli.py # typer CLI 入口
├── dwg2dxf.py # ODA File Converter 封装(目录级转换编排)
├── render.py # ezdxf → PNG/SVG 渲染核心
├── config.py # 参数 → ezdxf Configuration 映射
├── plotstyle.py # CTB 打印样式(占位)
└── batch.py # 批量 + 部分失败结果对象
测试
pip install -e ".[dev]" # 开发依赖(pytest / ruff / mypy / Pillow / fonttools)
pytest # 单元测试(无外部依赖)
pytest -m integration # 集成测试(需真实 DWG + ODA)
集成测试通过环境变量提供真实图纸:
CAD_TEST_DWG=E:/path/to/轴套.dwg pytest tests/test_integration.py -m integration
打包发布
# 构建 wheel + sdist
python -m build
# 上传 PyPI
python -m twine upload dist/*
产物 dist/cad2image-0.1.0-py3-none-any.whl 自带开源字体(Noto Sans SC / Noto Sans Mono)与 py.typed。
质量门禁
ruff check .
mypy src/
pytest
Metadata
Release files for cad2image 0.1.9
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| cad2image-0.1.9.tar.gz | 16.6 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| cad2image-0.1.9-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 33.2 MB
Release files / cad2image-0.1.9.tar.gz
| Download URL | cad2image-0.1.9.tar.gz |
|---|---|
| Size | 16.6 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9b7de95b2e685ddfa6affbec25bd82e0cc48bb5f47864761c2876479f65ae703
|
|
BLAKE2b-256 checksum How to use checksums |
014564206227fc2e7eb4403f2eddf01906f4b01b7f09f361b119e2e2f072a0d8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.4
|
Release files / cad2image-0.1.9-py3-none-any.whl
| Download URL | cad2image-0.1.9-py3-none-any.whl |
|---|---|
| Size | 16.6 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8fead7c0bee514c9865ccc93269d4f290bf3a8c6bdf11a14fdf7674b4d0afb7c
|
|
BLAKE2b-256 checksum How to use checksums |
c6fb7d8af95a6d1648eeb716e0d89702c1966365ac480b895dc5bca6c97d03db
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.4
|