你知道吗?python lxml 库也能用于操作 svg 图片

news2024/11/24 0:39:18

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

python lxml 库操作 svg 图片

    • lxml 操作 svg 图片示例
    • lxml 给 svg 图片添加新元素
    • lxml 删除 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))

📢📢📢📢📢📢
💗 你正在阅读 【梦想橡皮擦】 的博客
👍 阅读完毕,可以点点小手赞一下
🌻 发现错误,直接评论区中指正吧
📆 橡皮擦的第 837 篇原创博客

从订购之日起,案例 5 年内保证更新

  • ⭐️ Python 爬虫 120,点击订购 ⭐️
  • ⭐️ 爬虫 100 例教程,点击订购 ⭐️

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/169807.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

传输层协议:TCP协议(上)——协议结构、主要特点以及应用场景

简介 传输控制协议&#xff08;英语&#xff1a;Transmission Control Protocol&#xff0c;缩写&#xff1a;TCP&#xff09;是一种面向连接的、可靠的、基于字节流的传输层通信协议&#xff0c;由IETF的RFC 793定义。在简化的计算机网络OSI模型中&#xff0c;它完成第四层传…

xubuntu系统偶发自动登出

项目场景&#xff1a; 系统&#xff1a;xubuntu-16.04.3-desktop 问题描述 使用xubuntu系统期间&#xff0c;在root用户下进行相关开发&#xff0c;突然系统会回到普通用户登录界面&#xff0c;需要输入密码进入到普通用户下   它会终止所有打开的应用程序和进程&#xff0…

【Vue组件通信方式】

文章目录前言一、父子组件通信1、父传子①使用props接收父组件传递的属性② 使用$attrs接收父组件未在 props 和 emits 中定义的属性和事件③使用 $parent获取父组件的信息2、子传父① 使用 $emit传递信息给父组件② 使用$refs获取子组件的属性和事件二、自定义事件&#xff1a…

独家丨DeepMind科学家、AlphaTensor一作解读背后的故事与实现细节

一直以来&#xff0c;DeepMind的Alpha系列工作&#xff0c;AlphaGo、AlphaStar等致力于棋类和游戏应用中战胜人类&#xff0c;而两个月前发布的AlphaTensor则把目标指向了科学计算领域&#xff0c;意在为矩阵乘法等基本计算任务自动设计更高效的经典算法&#xff0c;这一工作一…

Burpsuite超详细安装教程(附安装包)

写在开头 Burp Suite 是用于攻击web 应用程序的集成平台&#xff0c;包含了许多工具。Burp Suite为这些工具设计了许多接口&#xff0c;以加快攻击应用程序的过程。所有工具都共享一个请求&#xff0c;并能处理对应的HTTP 消息、持久性、认证、代理、日志、警报。 接下来我来…

软件测试面试经 | 双非院校,从外包到外企涨薪85%,他的涨薪秘籍全公开

本文为霍格沃兹测试开发学社优秀学员跳槽笔记&#xff0c;测试开发进阶学习文末加群。 本身是一所不入流的院校毕业的一名建工类专业的瓜娃子&#xff0c;至今记得当初是因为找工作被培训公司忽悠才加入到这个行业的&#xff0c;抱着做着试试的想法这一干在深圳就是6年&#xf…

excel替换技巧:如何将手机号码的部分数字变成星号

每个销售员经常会接触大量客户&#xff0c;会用小本本记下众多客户的信息&#xff0c;而手机号码就是其中重要的一项。为了保护客户隐私&#xff0c;在公开的信息里销售员需要把客户手机号码的部分数字变成星号。比如说&#xff0c;把客户A的手机号码15867852976修改成158****2…

SpringMvc源码分析(三) 请求执行过程之获取MethodHandler

1.请求是如何关联到DispatcherServlet的 DispatcherServlet是Servlet的实现&#xff0c;遵循Servlet生命周期的规则。 Servlet的生命周期即其出生到死亡的过程中分别会调用Servlet里的以下方法&#xff1a; 加载和实例化&#xff1a;可以参考SpringMvc源码分析一 init方法…

【JavaEE】博客前端

目录 一、列表页 1.1导航条 1.2主题区域 1.2.1个人信息框 1.2.2 内容区 二、登录页 三、详情页 一、列表页 整体布局如下&#xff1a; 1.1导航条 导航条分为三块&#xff0c;整体都设置id为导航栏&#xff0c;然后左右分为导航栏左和导航栏右。左边靠左&#xff0c;右边靠…

计算机视觉Computer Vision课程学习笔记四之Region and Edge Descriptions

第四章讲了区域和边界的描述 包括最佳区域评估方法&#xff0c;多物体识别&#xff0c;标签算法&#xff0c;斑点标记 以及矩评估的方法和优劣 Region Description Simple measurements on binary images • Use for recognition, etc. • Generate region descriptions whic…

Win10+CMake+VS2017编译OpenCV4.5.5

第一步&#xff1a;准备工作1 下载opencv4.5.5下载OpenCV4.5.5&#xff0c;并解压到自己新建文件夹opencv下。2 下载opencv_contrib4.5.5下载opencv_contrib4.5.5&#xff0c;解压到上面的opencv文件夹中&#xff0c;并在opencv文件夹中新建一个build文件夹&#xff0c;用来存放…

第一天总结 之 用户管理界面的实现 之 添加操作 的实现

添加操作的实现 明确页面的跳转 找到 admin_adduser.jsp中 form表单 前端的添加页面展示 在表单中输入 信息 点击注册跳转到 from表单对应的 action地址 UserAddServlet 创建UserAddServlet 从前端的form表单中获取值 然后在service层 进行 业务操作 即将这些属性存放在 Ob…

私有部署与SaaS模式网站有什么区别

什么是SaaS SaaS 是 Software-as-a-Service 的简称&#xff0c;它是一种通过互联网提供软件的模式。 以官网为例&#xff0c;SaaS订阅的网站通常统一部署在SaaS提供商的云服务器上。用户通过自己的实际需求订购对应的网站系统服务&#xff0c;按订购的系统功能、使用流量/存储…

Word处理控件Aspose.Words功能演示:用Java从Word文档中提取文本

Aspose.Words For .NET是一种高级Word文档处理API&#xff0c;用于执行各种文档管理和操作任务。API支持生成&#xff0c;修改&#xff0c;转换&#xff0c;呈现和打印文档&#xff0c;而无需在跨平台应用程序中直接使用Microsoft Word。此外&#xff0c;API支持所有流行的Word…

凭记忆错题记录-

3、某种部件用在2000合计算机系统中&#xff0c;运行工作1000小时后&#xff0c;其中有4台计算机的这种部件失效&#xff0c;则该部件的千小时可靠性度R为()。 A.0.990 B.0.992 C.0.996 D.0.998 【参考答案】D  8、9、X509数字证书标准推荐使用的密码算法是(8)&#xff0c;而…

计算机视觉Computer Vision课程学习笔记八之Recognition识别 low level

第八章讲了全局图像识别的方法 距离 空间特征 简单的分类模型 Recognition (low level / global matching) Task – from a description of the image in terms of “good” features (not just blobs) extract a meaning • Detect • Classify • Etc. • Techniques – Te…

C++动态规划超详细总结

动态规划首先来介绍一下动态规划&#xff0c;但我不想用过于官方的语言来介绍。动态规划是一种思想&#xff0c;它常用于最优解问题&#xff08;即所有问题包括所有子问题的解为最优解&#xff09;&#xff0c;它有点像递推&#xff0c;是在已知问题的基础上解决其他问题。这种…

【openWrt】安装后进行定制

修改openWrt管理后台默认端口vim /etc/config/uhttpd修改如下图内容然后重启uhttpd服务即可生效etc/init.d/uhttpd restart修改openWrt软件包源可以在openwrt后台改也可以在/etc/opkg/distfeeds.conf直接改vim /etc/opkg/distfeeds.conf配置如下src/gz handsomemod_core https:…

通讯录的实现

问天下谁与争锋&#xff0c;唯我傲视苍穹 此句赠与在看文章的你 该通讯录使用的语言是C语言&#xff0c;涉及的知识有动态开辟内存&#xff0c;和文件内存管理。 动态开辟内存是用来不断给通讯录增加容量的 文件管理是用来将通讯录的信息存储到文件里。 我会先从简单的写起&am…

公司裁员70%,小组从20个人降到5个人,年底公司耍无赖,全员打绩效C,就为了不发年终奖!...

年终奖写进合同&#xff0c;公司还能耍赖不给吗&#xff1f;一位网友吐槽&#xff1a;坐标小公司&#xff0c;公司裁员70%&#xff0c;自己组从20个人降到5个人。现在年底了&#xff0c;公司耍无赖&#xff0c;全员打绩效C&#xff0c;就为了不发年终奖&#xff01;年终奖都是写…