如何在不调整其内容大小的情况下使 SVG 图像的视口变为正方形?
How to make the viewport of an SVG image square, without resizing its contents?
我有一个 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) 我需要使较短的边与较长的边相等,以使其内容不会失去其原始比例的方式(=> 不要拉伸),他们需要到达 canvas.
的正中心
示例:将左侧图像转换为右侧图像。 (边框不是实际路径而是视图框)
编程语言和工具无所谓。我只需要可以应用于许多文件的东西(在 bash 脚本中)。因此,欢迎使用带有第三方库解决方案的 imagemagick、inkscape、python。
如果使用 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
这不会放大任何边界框线,只会放大图像。
玩你的测试 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>
所以假设原始参数是: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
然后只需编写一个脚本 search/parse/replace viewBox
文本文件中的文本...我不在 [=52 中编写代码=] 但在 C++ 中只是 "few" 行代码(注意一些 SVG 是 ASCII 有些是 UNICODE).
我有一个 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) 我需要使较短的边与较长的边相等,以使其内容不会失去其原始比例的方式(=> 不要拉伸),他们需要到达 canvas.
的正中心示例:将左侧图像转换为右侧图像。 (边框不是实际路径而是视图框)
编程语言和工具无所谓。我只需要可以应用于许多文件的东西(在 bash 脚本中)。因此,欢迎使用带有第三方库解决方案的 imagemagick、inkscape、python。
如果使用 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
这不会放大任何边界框线,只会放大图像。
玩你的测试 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>
所以假设原始参数是: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
然后只需编写一个脚本 search/parse/replace viewBox
文本文件中的文本...我不在 [=52 中编写代码=] 但在 C++ 中只是 "few" 行代码(注意一些 SVG 是 ASCII 有些是 UNICODE).