一款将 PNG 图片批量转换为 SVG 矢量图形的工具,特别适用于处理包含红色(#DC0019)和白色(#FEF9F9)两种颜色的图片。
- 批量处理: 自动扫描并处理
input目录中的所有 PNG 文件 - 颜色提取: 基于红色和白色两种颜色进行图像追踪
- 自动清理: 转换完成后自动清理临时文件和非 SVG 文件
- 错误处理: 完善的错误处理机制,确保转换流程稳定可靠
png-2-svg/
├── input/ # 存放待转换的 PNG 文件
├── output/ # 转换后的 SVG 文件输出目录
├── temp/ # 临时文件目录(自动创建和清理)
└── index.js # 主程序入口
npm install| 命令 | 说明 |
|---|---|
npm run png-2-svg |
执行 PNG 转 SVG 转换 |
- 将待转换的 PNG 文件放入
png-2-svg/input目录 - 运行命令:
npm run png-2-svg
- 转换后的 SVG 文件将保存在
png-2-svg/output目录
在 index.js 文件中可以修改以下配置:
| 参数 | 默认值 | 说明 |
|---|---|---|
RED |
#DC0019 |
目标红色值 |
WHITE |
#FEF9F9 |
目标白色值 |
inputDir |
./input |
输入目录路径 |
outputDir |
./output |
输出目录路径 |
turdSize |
2 |
图像追踪参数,过滤噪点 |
optTolerance |
0.2 |
优化容差 |
threshold |
128 |
二值化阈值 |
输入要求:
- 仅支持 PNG 格式图片
- 图片应包含红色(#DC0019)和白色(#FEF9F9)两种主要颜色
- 图片尺寸建议不超过 1024x1024 像素
输出格式:
- SVG 矢量图形
- 保留原始图片尺寸
- 包含红色和白色两个 path 图层
Q1: 转换失败或输出为空
可能原因:
- 图片格式不正确,非 PNG 格式
- 图片中不包含目标红色或白色
- 文件权限问题
解决方案:
- 确保输入文件为 PNG 格式
- 检查图片颜色是否匹配目标颜色值
- 检查目录读写权限
Q2: 转换后的 SVG 显示异常
可能原因:
- 图片分辨率过高
- 图片颜色复杂,包含大量噪点
解决方案:
- 尝试调整
turdSize参数过滤噪点 - 降低输入图片分辨率
Q3: 临时文件未清理
解决方案:
- 运行
npm run png-2-svg:clean手动清理 - 检查目录权限是否允许删除文件
核心转换流程:
- 读取 PNG 图片,提取红色和白色区域生成 mask
- 使用 Potrace 库将 mask 转换为 SVG path
- 合并红色和白色 path 生成最终 SVG
- 清理临时文件
sharp: 高性能图片处理库,用于图像解码和 mask 生成potrace: 位图转矢量图形库,用于 SVG path 生成
一款将单个 SVG 文件按指定 x 坐标拆分为两个独立 SVG 文件的工具。适用于将 SVG 精灵图(Sprite Sheet)中水平排列的多个图标拆分为独立文件。
- 路径级拆分: 解析 SVG 路径数据中的 M(moveto)命令,按子路径起始 x 坐标精确分组
- viewBox 偏移: 第二个 SVG 的 viewBox 从指定坐标 (split_x, split_y) 开始,确保起始原点坐标精确
- 属性保留: 自动保留原始 path 元素的 fill、stroke、fill-rule 等属性
- 命令行参数: 支持通过命令行参数自定义输入文件、输出目录和拆分坐标
- 异常处理: 文件不存在、无 path 元素、无有效子路径等情况均有明确错误提示
svg-split/
├── bottom-icon.svg # 源 SVG 文件
├── output/ # 拆分后的 SVG 文件输出目录(自动创建)
│ ├── bottom-icon-1.svg # 第一个 SVG(x < split_x 的子路径)
│ └── bottom-icon-2.svg # 第二个 SVG(x >= split_x 的子路径)
└── index.py # 主程序入口
- Python 3.6+(仅使用标准库,无需安装额外依赖)
默认方式(使用默认参数):
python svg-split/index.py默认读取 svg-split/bottom-icon.svg,输出到 svg-split/output/,拆分坐标为 x=428, y=92。
自定义参数:
python svg-split/index.py --input 源文件.svg --output 输出目录 --split-x 500 --split-y 100| 参数 | 缩写 | 默认值 | 说明 |
|---|---|---|---|
--input |
-i |
同目录下 bottom-icon.svg |
输入 SVG 文件路径 |
--output |
-o |
同目录下 output 文件夹 |
输出目录路径 |
--split-x |
— | 428 |
拆分 x 坐标,第二个 SVG 的起始 x 坐标 |
--split-y |
— | 92 |
拆分 y 坐标,第二个 SVG 的起始 y 坐标 |
- 解析 SVG 文件中所有
<path>元素的d属性 - 按
M(moveto)命令将路径数据拆分为独立子路径 - 根据每个子路径的起始 x 坐标进行分组:
- 起始 x < split_x → 归入第一个 SVG
- 起始 x >= split_x → 归入第二个 SVG
- 第一个 SVG 的 viewBox 从原点
(0, 0)开始 - 第二个 SVG 的 viewBox 从
(split_x, split_y)开始
以默认参数(split_x=428, split_y=92)拆分 bottom-icon.svg(2249×299)为例:
| 输出文件 | 尺寸 | viewBox | 内容 |
|---|---|---|---|
bottom-icon-1.svg |
428 × 299 | 0 0 428 299 |
左侧图标区域 |
bottom-icon-2.svg |
1821 × 207 | 428 92 1821 207 |
右侧文字区域,起始原点 (428, 92) |
Q1: 拆分后 SVG 显示不完整
可能原因:
- 拆分坐标设置不当,部分子路径被错误分组
- 子路径的绘制范围超出了 viewBox 区域
解决方案:
- 检查
--split-x和--split-y参数是否与实际图标边界匹配 - 使用 SVG 查看器检查原始文件中各子路径的坐标分布
Q2: 提示"SVG 文件中未找到 path 元素"
可能原因:
- 输入文件不是有效的 SVG 文件
- SVG 中使用了
<g>、<rect>、<circle>等非 path 元素
解决方案:
- 确认输入文件为标准 SVG 格式
- 当前版本仅支持
<path>元素,其他元素需先转换为 path
Q3: 子路径分组不正确
可能原因:
- 某些子路径的起始 x 坐标在拆分边界附近
- 子路径内部坐标跨越了拆分边界
解决方案:
- 微调
--split-x参数值 - 检查原始 SVG 中子路径的实际坐标范围
核心拆分流程:
- 使用
xml.etree.ElementTree解析 SVG XML 结构 - 使用正则表达式
\s+(?=M\s+[-\d.])在 M 命令处分割路径数据 - 提取每个子路径的起始 x 坐标进行分组
- 通过 viewBox 偏移实现第二个 SVG 的坐标原点设置
- 保留原始 path 属性(fill、stroke、fill-rule 等)