在Python中获取SVG文本大小
我正在用Python生成SVG图像(纯Python,没有使用外部库)。我想知道在正确放置文本元素之前,它的大小会是多少。有没有什么好的方法可以做到这一点?我查看了
2 个回答
1
我之前也遇到过同样的问题,不过我用的是可变宽度的字体。我解决这个问题的方法是,先把我想要的文本元素(正确的字体和内容)写入一个svg文件,然后在我电脑上用Inkscape这个软件把它渲染成一个临时的png文件。接着,我读取这个png文件的尺寸(从文件头提取),然后删除临时的svg和png文件,最后用这个结果来放置文本和周围的元素。
我发现用90的DPI来渲染图形,能给我需要的准确数字,或者说是svgwrite整体使用的原始数字。-D是一个标志,用来确保只渲染可绘制的元素,也就是文本。
os.cmd(/cygdrive/c/Program\ Files\ \(x86\)/Inkscape/inkscape.exe -f work_temp.svg -e work_temp.png -d 90 -D)
我用这些函数来提取png的尺寸,具体可以在这个链接找到,注意我稍微调整了一下以适应python3(仍然可以在python2中使用)
def is_png(data):
return (data[:8] == b'\x89PNG\r\n\x1a\n'and (data[12:16] == b'IHDR'))
def get_image_info(data):
if is_png(data):
w, h = struct.unpack('>LL', data[16:24])
width = int(w)
height = int(h)
else:
raise Exception('not a png image')
return width, height
if __name__ == '__main__':
with open('foo.png', 'rb') as f:
data = f.read()
print is_png(data)
print get_image_info(data)
虽然这个方法有点笨重,但确实有效。
1
这件事可能会比较复杂。首先,你需要了解一下SVG规范中关于文本的章节。假设你想要获取普通的text
元素的宽度,而不是textpath
元素,至少你需要做以下几件事:
- 解析字体选择属性、间距属性,并读取
xml:space
属性,以及writing-mode
属性(这个属性可以是从上到下,而不仅仅是从左到右和从右到左)。 - 根据以上信息,打开正确的字体,读取字形数据,并提取你文本字符串中每个字形的宽度和高度。光是找到字体就可能是一项大工程,因为字体文件可能藏在很多地方。
- (可选)查看字符串中是否有可能的连字(这取决于语言),如果字体中存在,就用正确的字形替换它们。
- 将所有字符和空格的宽度加起来,空格的宽度取决于间距属性和(可选)可能的字距调整。
一个可能的解决方案是使用pango库。你可以在py-gtk找到它的Python绑定。不幸的是,除了少数一些示例,Python绑定的文档相对较少。不过,它可以处理字体加载和确定Layout
的范围等细节。
另一种方法是研究你浏览器中的SVG渲染器。但是,例如,Firefox对SVG文本的支持是有限的。