如何在不调整其内容大小的情况下使SVG图像的视口成为正方形?

时间:2018-03-08 17:18:36

标签: python svg imagemagick inkscape

我有一个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>

视箱不是方形的(448!= 512)我需要使较短的边缘等于较长的边缘,使其内容不会失去其原始比例(=>不拉伸),并且他们需要到达画布的确切中心。

示例:将左侧的图像转换为右侧的图像。 (边框不是实际路径,而是视图框)

Example

编程语言和工具无关紧要。我只需要一些可以应用于许多文件的东西(在bash脚本中)。因此欢迎使用imagemagick,inkscape,python和第三方库解决方案。

2 个答案:

答案 0 :(得分:5)

使用您的测试svg(使用Internet Explorer作为查看器)显示,在没有定义viewBox的情况下更改width,height SVG不会改变它们的方面(没有拉伸只是缩放和平移)所以不需要使用所有矩阵都可以单独用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>

preview

因此,假设原始参数为: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 )。

答案 1 :(得分:2)

如果使用ImageMagick 7,您可以执行以下操作:

magick -density X -colorspace sRGB file.svg -background white -gravity center -extent "%[fx:max(w,h)]x%[fx:max(w,h)]" result.png


如果使用ImageMagick 6,则需要先计算最大尺寸,所以

maxsize=$(convert -density X -colorspace sRGB file.svg format "%[fx:max(w,h)]" info:)
convert -density X -colorspace sRGB file.svg -background white -gravity center -extent ${max_size}x${max_size} result.png

这不会放大任何边界框线,只会放大图像。