SVG路径指令中贝塞尔曲线拟合位图轮廓

先把位图变成可验证的轮廓

把位图转成 SVG,真正要解决的不是“描边”,而是三件事:哪些像素属于前景、哪些边界是孔洞、曲线允许偏离原轮廓多少。下面给出一条可执行流程:二值化、提取层级轮廓、简化点列、拟合三次贝塞尔曲线,再用栅格化结果验收。

先固定坐标和分割规则。黑色前景、白色背景可以从灰度值 <128 开始测试;带透明通道的素材优先使用 alpha,而不是先灰度化。抗锯齿像素是前景与背景的混合值,阈值升高可能让亮色前景收缩,实际位移取决于边缘灰度梯度,因此不能把 128 当成通用答案。

  1. 记录原图宽高,例如 800×600,并确定像素中心或像素边界作为轮廓坐标。
  2. 分别测试固定阈值、Otsu 和自适应阈值;用面积变化与边界叠加结果选择方案。
  3. 断裂边界需要闭运算时,明确使用的结构元素,例如 3×3 矩形。闭运算顺序是先膨胀、再腐蚀;若面积变化超过业务允许范围,就不要继续增大结构元素。

保住孔洞,再用 RDP 减少节点

轮廓提取要同时保留外轮廓、孔洞和父子关系。Suzuki–Abe 可在指定 4 邻接或 8 邻接后提取层级轮廓;对角相接像素在两种规则下可能得到不同拓扑,必须在参数记录中写明。Marching Squares 适合从网格标量值提取等值线,不能把它和普通边界跟踪混为一谈。

每个独立区域从 M 开始,孔洞使用独立子路径,不能用 L 跨区域连接。使用 nonzero 填充时,外轮廓与孔洞通常采用相反方向;使用 evenodd 时方向不影响填充,但子路径仍须闭合。

用 Ramer–Douglas–Peucker(RDP)删除距离基准线不超过 epsilon 的中间点。原图坐标可先从 epsilon=1 像素测试;若输出放大比例为 s,目标坐标容差为 epsilon_out 时,原图容差应换算为 epsilon_src=epsilon_out/s。

  • 闭合轮廓不要直接当开放折线处理,应选择稳定切分点,或使用闭合曲线简化算法。
  • 转角超过约 30°~45° 的点可作为保留尖角的起始规则,直角徽标应优先保留点而不是强行曲线化。
  • 每次提高 epsilon 后,重新检查面积相对误差、孔洞数量和最大边界距离;任一项超出目标,就退回上一个参数。

按尖角切段,再拟合 C 曲线

三次贝塞尔曲线的 C 指令包含两个控制点和一个终点。其公式为 B(t)=(1-t)^3P0+3(1-t)^2tP1+3(1-t)t^2P2+t^3P3,其中 t∈[0,1]。尖角用 L,平滑段才适合用 C;在尖角处硬接一条曲线,常会产生圆角或回钩。

对一段轮廓设端点为 P0、P3,端点单位切向量为 T0、T1,可令 P1=P0+aT0、P2=P3-bT1。a、b不能由公式固定决定,应通过最小二乘或带误差约束的搜索求解;采样点权重、端点切线是否固定,也要明确记录。

  1. 先按尖角和明显曲率变化切分,保留尖角点。
  2. 每段拟合一条或少量 C 曲线,计算采样轮廓与拟合曲线的最大双向距离。
  3. 若误差超过阈值,在误差最大处切分,重新估计两侧切线;若出现控制点越过轮廓,缩短控制柄或改用直线。

可把目标误差设为 viewBox 对角线的 0.1%,同时设置绝对像素上限。这个比例只是可复现的起点,图标、字体和大尺寸插画的合适上限取决于显示尺寸与用途,不能直接互换。

生成 SVG 后按四项指标验收

闭合路径应以 Z 结束,但 Z 只会从当前终点补一条直线回到起点。例如 M 10 20 C 20 5 40 5 50 20 C 40 35 20 35 10 20 Z 中,第二段曲线已经回到起点附近;若只写一段曲线,闭合处可能出现直线接缝。

800×600 位图可使用 viewBox="0 0 800 600"。坐标保留 3~6 位小数通常足够表达轮廓,但最终精度仍应由目标误差决定。若改变 Y 轴方向,必须同时写出平移、缩放和变换顺序。

需要命令行验证时,可用 ImageMagick 7 生成掩膜:magick input.png -alpha extract -threshold 50% mask.pbm;再用 Potrace 转换:potrace mask.pbm -s -o output.svg。Potrace 处理的是二值掩膜,不会恢复原始彩色设计路径,测试时应记录确切版本与阈值。

  • 将 SVG 栅格化到与原图相同尺寸,计算 IoU、面积相对误差和最大边界距离。
  • 核对子路径数量、孔洞数量、闭合状态和 fill-rule;孔洞变实先检查层级、方向和闭合。
  • 放大到 400%~800%,检查尖角、段间切线和控制点是否造成回钩。
  • 若整体偏移,检查阈值、像素中心定义和 viewBox;若比例变形,检查 preserveAspectRatio 与变换矩阵。

最终应保存一份参数记录:阈值方法、4/8 邻接、结构元素、RDP 容差、尖角阈值、最大拟合误差、坐标精度和工具版本。SVG 只近似当前像素轮廓;要恢复原始设计路径,必须取得矢量源文件或设计软件中的路径数据。

更多推荐

先分清两个“半径”:r决定窗口,σ决定衰减 高斯模糊调不出预期效果,常见原因不是公式错,而是把工具里的“半径”误当成同一个参数。卷积核半径 r决定参与计算的窗口大小,高斯标准差 σ决定距离中心越远的像素被压低得有多快。 当核半径为 r 时,

了解更多 >

圆角黑边的根源:边缘颜色和透明度没有对齐 圆角抗锯齿把边界覆盖率转换成 Alpha,所以一个边缘像素可能只有 A=128,约等于 0.502,而不是非黑即白。黑边、白边通常不是圆角算法本身造成的,而是 RGB 的存储方式、插值方式和合成公式

了解更多 >

卷积核如何改变图像局部结构 图像模糊和锐化,本质上都可以通过卷积核处理局部像素。卷积核在图像上逐点滑动,用邻域像素与核中的权重相乘并求和,从而重新计算每个输出像素。 以 3×3 卷积核为例,它包含 9 个权重,并且奇数尺寸能提供明确的中

了解更多 >

ICO容器的目录与图像数据分层 ICO不是一张固定尺寸的图片,而是一个可以装入多份图像数据的容器。它用文件头和目录记录每份图像的位置、大小及编码方式,应用程序据此选择合适的图标尺寸。 一个常见ICO文件可以拆成三层: 文件头:通常占6字

了解更多 >

先统一图像坐标与2x3矩阵含义 要用矩阵实现图片翻转或旋转,先要统一坐标系和画布范围。常见图像坐标以左上角为原点,x 轴向右增长,y 轴向下增长;宽度为 W、高度为 H 的图像,其有效像素坐标是 0 ≤ x < W、0 ≤ y &l

了解更多 >