我有一个包含以下内容的 SVG 图像(可以说是一个简单的图标):
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M436 160c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-20V48c0-26.51-21.49-48-48-48H48C21.49 0 0 21.49 0 48v416c0 26.51 21.49 48 48 48h320c26.51 0 48-21.49 48-48v-48h20c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-20v-64h20c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-20v-64h20zm-74 304H54a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h308a6 6 0 0 1 6 6v404a6 6 0 0 1-6 6zM128 208c0-44.183 35.817-80 80-80s80 35.817 80 80-35.817 80-80 80-80-35.817-80-80zm208 133.477V360c0 13.255-10.745 24-24 24H104c-13.255 0-24-10.745-24-24v-18.523c0-22.026 14.99-41.225 36.358-46.567l35.657-8.914c29.101 20.932 74.509 26.945 111.97 0l35.657 8.914C321.01 300.252 336 319.452 336 341.477z"/></svg>
viewbox 不是正方形 (448!=512) 我需要让短边等于长边,这样它的内容就不会失去它们的原始比例(=> 不要拉伸(stretch)),并且它们需要到达 Canvas 的确切中心。
示例:将左侧图像转换为右侧图像。 (边框不是实际路径而是 View 框)
编程语言和工具并不重要。我只需要可以应用于许多文件的东西(在 bash 脚本中)。因此欢迎使用带有第三方库解决方案的 imagemagick、inkscape、python。
请您参考如下方法:
玩你的测试 svg(使用 internet explorer 作为查看器)表明,在没有定义 width,height 的情况下为 SVG 更改 viewBox 不会改变它们的方面(没有拉伸(stretch)只是缩放和平移),因此无需使用矩阵,所有这些都可以单独在 viewBox 中完成。这是你的例子:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
<path d="M436 160c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-20V48c0-26.51-21.49-48-48-48H48C21.49 0 0 21.49 0 48v416c0 26.51 21.49 48 48 48h320c26.51 0 48-21.49 48-48v-48h20c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-20v-64h20c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-20v-64h20zm-74 304H54a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h308a6 6 0 0 1 6 6v404a6 6 0 0 1-6 6zM128 208c0-44.183 35.817-80 80-80s80 35.817 80 80-35.817 80-80 80-80-35.817-80-80zm208 133.477V360c0 13.255-10.745 24-24 24H104c-13.255 0-24-10.745-24-24v-18.523c0-22.026 14.99-41.225 36.358-46.567l35.657-8.914c29.101 20.932 74.509 26.945 111.97 0l35.657 8.914C321.01 300.252 336 319.452 336 341.477z"/>
</svg>
所以你想将 448 更改为 512 但我们仍想使图像居中因此我们也需要调整 x0 位置(在相反方向上调整一半差异 (512-448)/2 = 32)。因此,将 viewBox 更改为:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-32 0 512 512">
<path d="M436 160c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-20V48c0-26.51-21.49-48-48-48H48C21.49 0 0 21.49 0 48v416c0 26.51 21.49 48 48 48h320c26.51 0 48-21.49 48-48v-48h20c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-20v-64h20c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-20v-64h20zm-74 304H54a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h308a6 6 0 0 1 6 6v404a6 6 0 0 1-6 6zM128 208c0-44.183 35.817-80 80-80s80 35.817 80 80-35.817 80-80 80-80-35.817-80-80zm208 133.477V360c0 13.255-10.745 24-24 24H104c-13.255 0-24-10.745-24-24v-18.523c0-22.026 14.99-41.225 36.358-46.567l35.657-8.914c29.101 20.932 74.509 26.945 111.97 0l35.657 8.914C321.01 300.252 336 319.452 336 341.477z"/>
</svg>
假设原始参数是:viewBox(x0,y0,xs0,ys0) 那么新参数就是viewBox(x1,y1,xs1,ys1)其中:
xs1= ys1 = max(xs0,ys0);
x1 = x0 + (xs0 - xs1)/2;
y1 = y0 + (ys0 - ys1)/2;
因为 SVG 只是文本文件 (XML),以防您没有 R/W 访问 SVG::viewBox 在你的环境中,然后只需编写一个脚本来搜索/解析/替换文本文件中的 viewBox 文本......我不在 python 中编写代码,而是在 C++将只是“几行”代码(注意一些 SVG 是 ASCII 一些是 UNICODE)。
