Python 如何使SVG图像的视口呈方形,而不调整其内容的大小?

Python 如何使SVG图像的视口呈方形,而不调整其内容的大小?,python,svg,imagemagick,inkscape,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 48h

我有一个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)我需要使较短的边与较长的边相等,以使其内容不会失去其原始比率(=>不拉伸),并且它们需要位于画布的确切中心

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


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

如果使用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作为查看器)显示,在未定义
宽度、高度的情况下更改svg的
viewBox
,不会改变它们的纵横比(无拉伸,只需缩放和平移)因此,不需要使用矩阵,所有这些都可以在
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>

因此,假设原始参数是:
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++只需要“很少”行代码(请注意,有些SVGASCII有些是UNICODE)。

感谢您提供的解决方案,但问题是我需要这个版本的SVG(:
@srush-r
。很抱歉,我不知道您所说的我的命令的SVG版本是什么意思。您可能可以编辑SVG文件以使视口为方形。但我怀疑这意味着编程可以读取、编辑和保存SVG文件。这是真的。我需要一个方形视口,可以通过更改页眉中的单个数字来实现。但是有more(这使问题对我来说很难):在vewport大小更改后,SVG图像的内容需要移动到中心。这给了我一个白色png图像(ImageMagick 7.0.10-27)如何添加示例SVG作为测试代码…我认为您必须在parrent
对象上添加变换矩阵才能正确地转换和修复比例,但这只是我第一次在没有任何证明或试验的情况下教授的…还定义了
宽度
高度
(通常在
视图框附近)?@Spektre问题是如何…构造很容易,您只需要包含缩放和转换的2D 3x3版本。但是没有用于测试和解释视口的SVG示例,我不会努力回答。我添加的答案看起来根本不需要矩阵
xs1= ys1 = max(xs0,ys0);
x1 = x0 + (xs0 - xs1)/2;
y1 = y0 + (ys0 - ys1)/2;