如何将常规SVG的<g>标签转换为含base64 PNG的<image>标签
关于这类SVG的标准命名
目前没有W3C官方指定的统一学名,业内通用的称呼是内嵌位图的SVG,部分场景下也会叫光栅化嵌入SVG、位图包装SVG,你所说的“伪SVG”是开发者圈子里比较通俗的叫法,交流时提这个称呼从业者基本都能理解。
实现方案优化
你设想的核心逻辑是可行的,但不用完全手写底层渲染逻辑,有现成的工具可以大幅简化开发:
浏览器端在线转换场景
优先用canvg库,实现步骤比原生canvas手写简单很多:
- 遍历原SVG的所有
<g>标签,为每个<g>单独生成一个临时最小SVG文件,viewBox设置为当前<g>调用getBBox()返回的边界框数值,把<g>的内容直接塞到这个临时SVG里 - 用
canvg把临时SVG渲染到一个离屏canvas上,直接调用canvas.toDataURL('image/png')就能拿到对应分组的base64编码PNG资源 - 新建目标SVG骨架,为每个分组生成对应的
<image>标签,x、y、width、height属性对应之前拿到的<g>边界框数值,xlink:href填生成的base64即可
这个方案不需要你自己处理SVG矢量元素的canvas渲染适配,所有SVG语法兼容的问题canvg都已经做了适配,开发量至少减少70%。
批量离线转换场景
用Inkscape的命令行模式就能实现,写个简单的遍历脚本即可:
- 解析原SVG提取所有
<g>标签和对应的边界框、属性 - 调用
inkscape命令把每个<g>单独导出为指定分辨率的PNG - 把所有PNG转成base64后拼装成目标SVG即可
适合大批量文件处理,不需要依赖浏览器环境,导出精度可以自由调整。
注意事项
处理的时候一定要先获取每个<g>的精确边界框,尤其是带transform变换的分组,要把变换后的坐标算对,不然生成的<image>位置会和原矢量SVG的布局不一致。
内容的提问来源于stack exchange,提问作者Alien13
相关产品推荐
相关产品推荐

