2017-04-19 5 views
0

我在python3中使用BeautifulSoup模块来修改我用Inkscape创建的一些svg文件。具体来说,我正在修改这些文件中的一些文本,并在某些情况下更改某些对象的颜色。我注意到,无论我做什么,所有文本的位置总是在输出svg文件中移动。 例如参见:svg in/out files + png versions为什么使用BeautifulSoup修改SVG文件时文本对象发生了变化?

这似乎是发生的是文本对象的大小是相对于原来的文件输出SVG不同。我可以将文本对象从输出文件复制到原始文件,我不再看到这种转变,但这是一个恼人的解决方案。

有没有人知道是什么原因导致文本对象大小发生这种变化,并且可以防止这种变化?

下面的代码的一个例子位我已经运行(输入和输出svgs的拷贝是在上面的链接):

from bs4 import BeautifulSoup 

svgFile = "test_in.svg" 
outputFile = "test_out.svg" 

svg = open(svgFile, 'r').read() 
soup = BeautifulSoup(svg, features = 'xml') 
texts = soup.findAll('text') 

for t in texts: 
    if t['id'] == 'testID': 
     print(t, '\n') 
     t.contents[0].string = 'new text' 
     print(t, '\n') 

# Output the edited SVG file 
f = open(outputFile, "w") 
f.write(soup.prettify()) 
f.close() 

虽然目前没有出现任何变化中的文本元素xml/svg树,所以我觉得问题必须从文件的其他部分进行更改。 (另外,我可以省略t.contents[0].string = 'new text'和文本运动仍会发生。)第一print(t)给出:

<text id="testID" inkscape:label="#text3581" sodipodi:linespacing="125%" style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Arial;-inkscape-font-specification:Arial" transform="matrix(0,1,-1,0,0,0)" x="449.63721" xml:space="preserve" y="-280.92737"><tspan id="tspan3583" sodipodi:role="line" style="font-size:14px;font-weight:normal;-inkscape-font-specification:Arial" x="449.63721" y="-280.92737">Text to change</tspan></text> 

第二打印(t)的输出看起来是完全一样的,不同之处'text to change'现在是'new text'

<text id="testID" inkscape:label="#text3581" sodipodi:linespacing="125%" style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Arial;-inkscape-font-specification:Arial" transform="matrix(0,1,-1,0,0,0)" x="449.63721" xml:space="preserve" y="-280.92737"><tspan id="tspan3583" sodipodi:role="line" style="font-size:14px;font-weight:normal;-inkscape-font-specification:Arial" x="449.63721" y="-280.92737">new text</tspan></text> 

任何见解将不胜感激!

+0

请发布一个文本对象的小svg示例,在您的转换过程中移动。 –

+0

编辑包括png版本的输入和输出svg文件 – Gingerbeardman

回答

1

发生了什么事是你通过插入新行和调用prettify()增加额外的空间。

<tspan id="tspan3583" sodipodi:role="line" style="font-size:14px;font-weight:normal;-inkscape-font-specification:Arial" x="449.63721" y="-280.92737"> 
    new text 
    </tspan> 

“新文本”前面还有四个空格。

通常这不会是一个问题。在XML中默认情况下,元素起始处的空格被删除。不幸的是你的SVG文件在您的文本元素以下属性:

xml:space="preserve" 

这是告诉你所关心的空间浏览器,并且希望他们能够保存和显示。

有两种解决方法:

  1. 停止添加新行和/或美化
  2. 检查,并从目标文本元素中所有的xml:space属性。或将值从"preserve"更改为"default"
+0

我知道这是几个月前,但我终于开始测试这个。解决方案1效果很好。我所要做的就是用'f.write(str(soup))'替换'f.write(soup.prettify())'。就像你指出的那样,这会停止添加新行和前导空格。 – Gingerbeardman

1

我有这个相同的问题。问题是,当bs4解析文件时,它将文本内容添加到新行中,所以在文本前后添加了额外的空白,这就是为什么它在svg内部移动的原因。

下面是您的输入svg文件的屏幕截图。你看到的文字是在同一行的标签

enter image description here

在你的输出SVG文件(如下图),你将看到的是,BS4解析后,“新文本”的内容是一个单独的行来自标签。还有一件事情是,在文本之前和之后现在有很多空白空间,这正是导致其在svg图像中位置偏移的原因。我刚才也有这个问题,不知道该解决方案是什么。

enter image description here

+0

我想出的噱头解决方案是在我的文本居中之前用bs4改变它。白色空间仍然被添加,但文字不会移动。现在我知道问题的实际来源,我可能会尝试花一些时间来想出更优雅的解决方案。感谢您指出了这一点。 – Gingerbeardman

相关问题