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

作者:梦想橡皮擦 时间:2022-08-09 04:37:23 

在大多数场景中,我们都用 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()

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

同时查看一下 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))

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

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

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))

来源:https://blog.csdn.net/hihell/article/details/128723910

标签:python,lxml,svg
0
投稿

猜你喜欢

  • Python+Selenium+PIL+Tesseract自动识别验证码进行一键登录

    2023-04-13 19:29:37
  • 利用SQL Server触发器实现表的历史修改痕迹记录

    2024-01-19 18:06:42
  • 利用Python找回微信撤回信息

    2022-11-21 22:34:03
  • pytorch获取vgg16-feature层输出的例子

    2021-04-16 20:56:47
  • 汇总数据库备份 还原 压缩与数据库转移的方法

    2009-01-19 14:07:00
  • Python Socket编程之多线程聊天室

    2021-03-23 21:01:02
  • 深入分析在Python模块顶层运行的代码引起的一个Bug

    2021-06-29 01:26:29
  • MySQL磁盘碎片整理实例演示

    2024-01-26 15:28:26
  • python matplotlib库绘制散点图例题解析

    2023-08-14 03:12:56
  • js实现遮罩层弹出框的方法

    2024-02-23 09:01:33
  • SqlServer中tempdb的日志机制原理解析及示例分享

    2024-01-15 20:31:38
  • python3 拼接字符串的7种方法

    2021-12-24 09:09:32
  • 使用虚拟机在VirtualBox+openEuler上安装部署openGauss数据库

    2024-01-21 22:45:53
  • python:socket传输大文件示例

    2022-04-18 19:44:26
  • python中k-means和k-means++原理及实现

    2022-01-17 10:52:07
  • python批量添加zabbix Screens的两个脚本分享

    2022-07-21 02:17:28
  • 基于Python的身份证验证识别和数据处理详解

    2021-04-22 04:43:09
  • 浅谈python中的多态

    2022-09-13 16:45:40
  • 深入解析MS-SQL锁机制

    2024-01-27 19:03:21
  • Mysql Explain 详解

    2010-12-03 16:09:00
  • asp之家 网络编程 m.aspxhome.com