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()
同时查看一下 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">橡皮擦</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))
来源:https://blog.csdn.net/hihell/article/details/128723910


猜你喜欢
- Linux下默认系统自带python2.6的版本,这个版本被系统很多程序所依赖,所以不建议删除,如果使用最新的Python3那么我们知道编译
- 这是一个非常简单的解决方案,柱状图中每一条柱都是一个 div,数据的大小呈现在 div 的宽或高上。 查看演示 例子下载实现的原理
- ASP开发中有用的函数(function)集合,挺有用的,请大家保留!'******************************
- 本文介绍了C#连接Oracle数据库的过程。通过instant client和ODP.net中的Oracle.DataAccess.dll,
- Python zipfile模块用来做zip格式编码的压缩和解压缩的,zipfile里有两个非常重要的class, 分别是ZipFile和Z
- 本文的重点就是如何创建一个PHP类来实现两个数间的加减乘除,这种类似于极简单的计算器功能。实现起来是非常简单的,继续往下看:这里简单给大家介
- 背景最近有一个需求需要自定义一个多继承abc.ABC与django.contrib.admin.ModelAdmin两个父类的抽象子类,方便
- 本文实例讲述了php实现搜索一维数组元素并删除二维数组对应元素的方法。分享给大家供大家参考。具体如下:定义一个一维数组一个二维数组如下$fr
- 这篇文章主要介绍了微信小程序顶部导航栏可滑动并选中放大,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋
- 本文实例讲述了Python实现利用最大公约数求三个正整数的最小公倍数。分享给大家供大家参考,具体如下:在求解两个数的小公倍数的方法时,假设两
- 本文实例讲述了Python排序搜索基本算法之归并排序。分享给大家供大家参考,具体如下:归并排序最令人兴奋的特点是:不论输入是什么样的,它对N
- 目录自动化测试框架1.基础层(通用层)2.功能层(页面层)3.业务层4.用例层4层框架对应的项目工程总结自动化测试框架项目自动化测试框架设计
- struct和C语言的很相似,模拟出class的功能,但是不完全的!没有构造函数等!struct的申明package mainimport
- 本文实例讲述了Python实现读取Properties配置文件的方法。分享给大家供大家参考,具体如下:JAVA本身提供了对于Properti
- 在做手机开发时,经常碰到一些比较耗时的操作,这个时候进度条就开始派上用场了。这个demo展示了ProgressBar进度条和Progress
- 数据库设计(Database Design)的概念:数据库设计是指对于一个给定的应用环境,构造最优的数据库模式,建立数据库及其应用系统,使之
- 包括安装时提示有挂起的操作、收缩数据库、压缩数据库、转移数据库给新用户以已存在用户权限、检查备份集、修复数据库等 (一)挂起操作 在安装Sq
- 进行深度学习时,对图像进行预处理的过程是非常重要的,使用pytorch或者TensorFlow时需要对图像进行预处理以及展示来观看处理效果,
- 本文实例讲述了JS实现淡入淡出图片效果的方法。分享给大家供大家参考,具体如下:效果:鼠标移入时,图片由半透明逐渐变成清晰,移出时,由清晰变为
- 本文实例讲述了JS密码生成与强度检测的方法。分享给大家供大家参考,具体如下:1. 生成强密码截图如下:相关代码如下:function get