python利用lxml库剩下操作svg图片

 更新时间:2023年01月21日 08:25:27   作者:梦想橡皮擦  
在大多数场景中,我们都用 lxml 库解析网页源码,但你是否知道,lxml 库也是可以操作 svg 图片的。本文就来和大家聊聊具体操作方法,希望对大家有所帮助

在大多数场景中,我们都用 lxml 库解析网页源码,但你是否知道,lxml 库也是可以操作 svg 图片的。我们可以使用 lxml 中的 etree 模块来解析 SVG 文件,然后使用 SVG 中的各种元素和属性来进行操作。

lxml 操作 svg 图片示例

在本篇博客的入门篇,我们首先使用一下 lxml 库解析 svg 文件,并修改它的颜色。

SVG 图片生成,可以查看 《Python 生成 svg 图片,一篇博客带你掌握 Python 与 svg 之间的操作》 这篇博客。

借用 svgwrite 库,生成一个红色背景的 svg 图片。

import svgwrite

dwg = svgwrite.Drawing('demo.svg', size=(100, 20), profile='tiny')
dwg.add(dwg.rect(insert=(0, 0), size=(100, 20), fill='red'))
phone_number = '橡皮擦'
dwg.add(dwg.text(phone_number, insert=(0, 15), fill='white', font_size=12))

dwg.save()

同时查看一下 svg 内容,如下所示。

<?xml version="1.0" encoding="utf-8" ?>
<svg baseProfile="tiny" height="20" version="1.2" width="100" xmlns="http://www.w3.org/2000/svg"
     xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xlink="http://www.w3.org/1999/xlink">
    <defs/>
    <rect fill="red" height="20" width="100" x="0" y="0"/>
    <text fill="white" font-size="12" x="0" y="15">橡皮擦</text>
</svg>

我们需要替换的内容是 fill="white" ,将其修改为 fill="#03a9f4"。使用 lxml 读取该文件,进行颜色替换。

from lxml import etree

# 解析SVG文件
svg_file = 'demo.svg'
with open(svg_file, 'rb') as f:
    svg_data = f.read()
    parser = etree.XMLParser(remove_blank_text=True)
    svg_tree = etree.fromstring(svg_data, parser)

# 修改颜色
for element in svg_tree.iter():
    if 'fill' in element.attrib:
        # 替换颜色
        element.attrib['fill'] = element.attrib['fill'].replace('white', '#03a9f4')

# 保存修改后的SVG文件
with open('modified_demo.svg', 'wb') as f:
    f.write(etree.tostring(svg_tree, pretty_print=True))

此时替换之后,再次查看 svg 图片源码内容,如下所示。

<svg xmlns="http://www.w3.org/2000/svg" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xlink="http://www.w3.org/1999/xlink" baseProfile="tiny" height="20" version="1.2" width="100">
  <defs/>
  <rect fill="red" height="20" width="100" x="0" y="0"/>
  <text fill="#03a9f4" font-size="12" x="0" y="15">&#27233;&#30382;&#25830;</text>
</svg>

重点注意 text 元素部分,发现 fill 属性的值已经被修改成最新的颜色了。

lxml 给 svg 图片添加新元素

使用 append() 函数可以给 svg 图片添加新元素,例如下述代码将添加一个矩形到图片中。

from lxml import etree

# 解析SVG文件
svg_file = 'demo.svg'
with open(svg_file, 'rb') as f:
    svg_data = f.read()
    parser = etree.XMLParser(remove_blank_text=True)
    svg_tree = etree.fromstring(svg_data, parser)

new_element = etree.Element('rect', x='5', y='5', width='50', height='20', style='fill:#03a9f4')
svg_tree.append(new_element)



# 保存修改后的SVG文件
with open('modified_demo.svg', 'wb') as f:
    f.write(etree.tostring(svg_tree, pretty_print=True))

这里矩形的定位并没有精确计算,实现的效果图如下所示。

lxml 删除 svg 图片中的元素

除新增外,还可以对 svg 中元素进行删除操作。示例代码如下所示。

from lxml import etree

# 解析SVG文件
svg_file = 'modified_demo.svg'
with open(svg_file, 'r') as f:
    svg_data = f.read()
    parser = etree.XMLParser(remove_blank_text=True)
    svg_tree = etree.fromstring(svg_data, parser)

# 通过 xpath 查找需要删除的元素
elements_to_remove = svg_tree.xpath("//text")
print(elements_to_remove)
for element in elements_to_remove:
    element.getparent().remove(element)

运行代码会发现通过 xpath 无法查找到目标元素 text,这时因为 SVG 文件中含有命名空间,导致 xpath 语法查询不到相应的元素,可以通过为 xpath 语法指定命名空间来解决这个问题。

添加命名空间之后的提取语法如下所示。

from lxml import etree

# 解析SVG文件
svg_file = 'modified_demo.svg'
svg_tree = etree.parse(svg_file)
root = svg_tree.getroot()


# 获取命名空间
ns = {'svg': root.nsmap[None]}
# 通过 xpath 查找需要删除的元素
elements_to_remove = svg_tree.xpath("//svg:text", namespaces=ns)

print(elements_to_remove)

尤其注意 xpath 部分需要使用 //svg:text 进行提取。

如果不提前生命 ns 变量,可以使用下述代码进行指定命名空间。

elements_to_remove = svg_tree.xpath("//svg:circle", namespaces={'svg': 'http://www.w3.org/2000/svg'})

有了上述基础之后,完整的 lxml 删除元素代码如下所示。

from lxml import etree

# 解析SVG文件
svg_file = 'modified_demo.svg'
svg_tree = etree.parse(svg_file)
root = svg_tree.getroot()


# 获取命名空间
ns = {'svg': root.nsmap[None]}
# 通过 xpath 查找需要删除的元素
elements_to_remove = svg_tree.xpath("//svg:text", namespaces=ns)

print(elements_to_remove)
for element in elements_to_remove:
    element.getparent().remove(element)

# 保存修改后的 SVG 文件
with open('modified_demo1.svg', 'wb') as f:
    f.write(etree.tostring(svg_tree, pretty_print=True))

以上就是python利用lxml库剩下操作svg图片的详细内容,更多关于python lxml操作svg的资料请关注脚本之家其它相关文章!

相关文章

  • Python通过websocket与js客户端通信示例分析

    Python通过websocket与js客户端通信示例分析

    网站大多使用 HTTP 协议通信,而 HTTP 是无连接的协议。只有客户端请求时,服务器端才能发出相应的应答, HTTP 请求的包也比较大,如果只是很小的数据通信,开销过大。于是,我们可以使用 websocket 这个协议,用最小的开销实现面向连接的通信。
    2014-06-06
  • Python基础面向对象之继承与派生详解

    Python基础面向对象之继承与派生详解

    这篇文章主要为大家介绍了Python基础面向对象之继承与派生详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-11-11
  • Qt5 实现主窗口状态栏显示时间

    Qt5 实现主窗口状态栏显示时间

    这篇文章主要介绍了Qt5 实现主窗口状态栏显示时间,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-03-03
  • Anaconda入门使用总结

    Anaconda入门使用总结

    个人尝试了很多类似的发行版,最终选择了Anaconda,因为其强大而方便的包管理与环境管理的功能。该文主要介绍下Anaconda,对Anaconda的理解,并简要总结下相关的操作
    2018-04-04
  • 浅谈Python如何获取excel数据

    浅谈Python如何获取excel数据

    这篇文章主要介绍了Python如何获取excel数据,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-10-10
  • python 文件转成16进制数组的实例

    python 文件转成16进制数组的实例

    今天小编就为大家分享一篇python 文件转成16进制数组的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-07-07
  • python利用proxybroker构建爬虫免费IP代理池的实现

    python利用proxybroker构建爬虫免费IP代理池的实现

    这篇文章主要介绍了python利用proxybroker构建爬虫免费IP代理池,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-02-02
  • 使用Django实现把两个模型类的数据聚合在一起

    使用Django实现把两个模型类的数据聚合在一起

    这篇文章主要介绍了使用Django实现把两个模型类的数据聚合在一起,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-03-03
  • python中关于py文件之间相互import的问题及解决方法

    python中关于py文件之间相互import的问题及解决方法

    这篇文章主要介绍了python中关于py文件之间相互import的问题,本文用一个例子演示下如何解决python中循环引用的问题,需要的朋友可以参考下
    2022-02-02
  • Python的3种运行方式:命令行窗口、Python解释器、IDLE的实现

    Python的3种运行方式:命令行窗口、Python解释器、IDLE的实现

    这篇文章主要介绍了Python的3种运行方式:命令行窗口、Python解释器、IDLE的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-10-10

最新评论