termtosvg 录制终端并导出 SVG 动画
唠唠闲话
日常的开发工作中,有时我们需要记录并展示终端操作的过程,无论是为了演示、教学还是文档编写。尽管有多种工具可以完成这项工作,termtosvg
是一个不仅能录制终端会话,还能以动态或静态的SVG文件格式展示的工具,使得分享和展示变得格外方便和直观。
项目地址:https://github.com/nbedos/termtosvg
将 SVG 动画转为 GIF 的过程可以使用 chrome-driver
来自动化浏览器操作,然后捕获动画的屏幕录像,再将其转换为 GIF。以下是一个基本的步骤指南:
安装所需软件
- 安装 Chrome 和 ChromeDriver
1 | wget -O chromedriver.zip http://chromedriver.storage.googleapis.com/`curl -sS chromedriver.storage.googleapis.com/LATEST_RELEASE`/chromedriver_linux64.zip |
chrome 需安装旧版:
https://vikyd.github.io/download-chromium-history-version/#/
- 安装 Python 和依赖库
1
pip install selenium pillow imageio
编写脚本
- 使用 Selenium 捕获 SVG 动画
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
import time
from PIL import Image
import imageio
# 设置 ChromeDriver 路径
chrome_driver_path = '/path/to/chromedriver'
# 初始化 Chrome 选项
chrome_options = Options()
chrome_options.add_argument('--headless') # 启用无头模式
chrome_options.add_argument('--disable-gpu')
chrome_options.add_argument('--window-size=800,600')
# 创建 Chrome 服务
service = Service(chrome_driver_path)
# 初始化 WebDriver
driver = webdriver.Chrome(service=service, options=chrome_options)
# 打开包含 SVG 动画的网页
driver.get('file:///path/to/your/svg_animation.html')
# 捕获一系列的屏幕截图
screenshots = []
for i in range(30): # 假设动画持续 30 帧
time.sleep(0.1) # 调整捕获频率
screenshot = driver.get_screenshot_as_png()
image = Image.open(BytesIO(screenshot))
screenshots.append(image)
# 关闭 WebDriver
driver.quit()
# 将截图保存为 GIF
screenshots[0].save('output.gif', save_all=True, append_images=screenshots[1:], duration=100, loop=0)
详细说明
-
设置 ChromeDriver 路径和选项
- 确保
chrome_driver_path
指向正确的 ChromeDriver 可执行文件。 - 使用
--headless
选项可以使浏览器在后台运行,而不会弹出窗口。
- 确保
-
捕获 SVG 动画
- 使用
driver.get()
打开包含 SVG 动画的网页。如果 SVG 动画嵌入在 HTML 文件中,可以使用file:///path/to/your/svg_animation.html
来打开本地文件。 - 使用
get_screenshot_as_png()
方法捕获当前屏幕的截图,并存储在一个列表中。
- 使用
-
保存为 GIF
- 使用
PIL
库将截图列表保存为 GIF。save_all=True
表示保存所有帧,append_images=screenshots[1:]
用于添加后续的帧,duration=100
设置每帧的显示时间(毫秒),loop=0
表示无限循环。
- 使用
这样,你就可以将包含 SVG 动画的网页捕获并转换为 GIF。根据实际情况,可能需要调整捕获帧数和频率以获得理想的结果。
SVG
SVG 是可伸缩矢量图形(Scalable Vector Graphics)的缩写,它是一种基于 XML 语法的图像格式,用于描述二维矢量图形。与传统的点阵图像(如 JPEG 或 PNG)不同,SVG 图像使用数学表达式来描述形状和颜色等,不会因为放大而失真。
SVG 的特点主要包括:
- 矢量性: 图像是由直线、曲线和形状组成的,这意味着无论怎样缩放图像,都能保持边缘的清晰度,不会出现像素化。
- 可修改: 由于 SVG 文件是文本文件,可以使用文本编辑器来编辑它们。你可以很容易地修改图像的颜色、形状和大小。
- DOM 接口: SVG 图像是通过 DOM(文档对象模型)的接口来操作的,这使得你可以用 JavaScript 和 CSS 如同操作 HTML 元素一样来操作 SVG 元素。
- 兼容性: 大多数现代浏览器都支持 SVG 格式的显示和脚本操作,移动设备亦然。
- 互动和动画: SVG 支持在图像内嵌入互动事件处理器,例如鼠标点击、鼠标移动等,还可以使用 SVG 的
<animate>
元素来制作动画效果。 - 脚本化与样式化: 可以通过 JavaScript 进行脚本化操作,通过 CSS 进行样式设计,方便与Web页面整合。
- 可访问性: 文本格式允许描述图形内容,这对于搜索引擎优化(SEO)和可访问性辅助技术(如屏幕阅读器)来说是非常重要的。
- 性能: 对于包含大量形状或路径的复杂图形,SVG 文件的大小可能会比传统位图小很多,特别是在缩放时。
- 打印友好: 由于 SVG 是矢量图形,它在高分辨率打印设备上保持高质量。
SVG 特别适合于复杂图形(如地图)、图标、徽标、图表和一些基于线条绘制的艺术作品等。随着 Web 技术的不断发展,SVG 越来越多地用于网页设计中,以其灵活性和功能丰富性受到设计师和开发者的青睐。
TermToSVG
termtosvg
是一个基于 Python 命令行工具,可以捕捉终端会话,并将其转换成高质量的 SVG 动画。但该项目作者从 2020 年开始不再进行维护,仓库目前已归档。
示例
我们以 askchat 为例,演示常用的 termtosvg
参数用法,并对已有模板进行魔改,制作 Mac 终端的版本。
效果如下:
基本示例
1 | termtosvg my_session.svg |
录制当前的终端会话,并将其保存为 my_session.svg
。
设置动画循环之间的暂停时间
1 | termtosvg my_session_delayed.svg -D 2000 |
录制当前会话,并设置动画循环之间的暂停时间为 2 秒:
指定终端的大小
默认占满屏幕宽度,效果不好,可通过 -g
参数指定终端的大小。
1 | termtosvg my_session_80x24.svg -g 80x24 |
以 80 列 24 行的大小录制并渲染终端会话。
录制静态帧
1 | termtosvg -s my_frames/ |
这将输出静态帧,而不是动画。录制结果将保存到 my_frames
目录中,每一帧都是一个独立的 SVG 文件。
使用模板
内置的模板列表:https://nbedos.github.io/termtosvg/pages/templates.html
1 | termtosvg my_session_dracula.svg -t dracula |
dracula
模板提供了一种暗色系的显示风格,使用该模板录制并渲染会话:
也可以尝试不同的模板,例如 solarized_dark
:
1 | termtosvg my_session_solarized_dark.svg -t solarized_dark |
-t
后边也可以接自定义的模板文件路径。
更多例子
参看文档:
- https://github.com/nbedos/termtosvg/blob/develop/man/termtosvg.md
- https://nbedos.github.io/termtosvg/pages/examples.html
模板修改指南
在 termtosvg 中,模板是SVG文件,用于嵌入动画。使用模板可以实现以下功能:
- 自定义终端颜色主题和字体:用户可以通过模板中的
style
元素定义终端颜色和字体样式,使得动画更符合个人审美或项目需求。 - 添加终端用户界面或窗口框架:通过 SVG 模板,可以为动画添加类似实际终端窗口的视觉框架,增加真实感和美观性。
- 交互式动画:例如播放/暂停按钮,使用户能够控制动画的播放过程,提高用户体验。
模板结构
TermToSVG 模板结构:
1 |
|
模板结构和各部分的作用:
svg
元素(ID “terminal”):这是 SVG 文件的最外层容器defs
元素:这是一个定义容器,用来存储 SVG 中使用的定义,如样式和脚本等。包括:termtosvg:template_settings
元素:termtosvg 特有的设置,用于定义终端的尺寸(列和行数)和动画的渲染方法("css"代表使用CSS动画,"waapi"代表使用Web Animations API)。这些设置告诉 termtosvg 如何渲染终端动画。style
元素(ID “generated-style”):这里的样式将被 termtosvg 在生成动画时自动覆盖,通常用于动画效果的实现。- 另一个
style
元素(ID “user-style”):这里的样式由模板创建者定义,通常包含终端的颜色主题,不会被termtosvg覆盖,允许用户自定义终端的视觉样式。
- 内部
svg
元素(ID “screen”):这个元素是动画实际展示的区域,保持动画内容的适当比例和定位。 script
元素(ID “generated-js”):这里的脚本将在使用"waapi"渲染方法时由 termtosvg 覆盖,通常包含动画的控制逻辑,如播放和暂停功能。
模板定制
模板定制的基本思想是,termtosvg会保留它未修改的模板元素。因此,您可以:
- 通过修改带有id "user-style"的
style
元素的内容来自定义动画样式:可以自定义动画的颜色主题、字体等样式,以符合个人或项目的视觉需求。 - 添加新的
script
元素以在动画中嵌入JavaScript代码:可以通过添加JavaScript代码增加动画的交互性或实现特定功能。 - 添加其他SVG元素,只要它们不是带有id "screen"的
svg
元素的子元素:可以自由地添加额外的视觉元素或装饰,只要它们不干扰动画的主要显示区域。
希望这些信息以及默认模板的代码足以帮助您开始进行模板定制。如果需要帮助,随时提交问题。
自定义颜色主题或字体
终端颜色主题在带有 id “user-style” 的 style
元素中指定,并且必须定义以下所有类:foreground
, background
, color0
, color1
, …, color15
。字体相关属性也可以与颜色主题一起指定。下面是一个示例。
1 | <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="terminal" baseProfile="full" viewBox="0 0 656 325" width="656" version="1.1"> |
自定义终端用户界面
1 |
|
完整示例:window_frame.svg
CSS进度条
嵌入JavaScript
在新的script
元素中添加代码。
完整示例:window_frame_js
将动画限制为单次循环
对于使用CSS的模板,简单地添加一个自定义样式元素,指定循环次数,如下所示:
1 | <style type="text/css" id="user-style"> |
完整示例在此:gjm8_single_loop
自定义模板
我们基于 window_frame.svg 进行魔改。原始模板的图标配色看着不适应,且边框棱角明显,我们将其修改为 Mac 风格,修改后的模板下载地址:mac_frame。
效果对比
原始效果:
1 | termtosvg my_session_with_frame.svg -t window_frame |
1 | # 下载模板 |
显示效果:
修改内容
主要修改了底部对图标样式的定义,将原始的 class
属性改为 style
属性,并修改了 rx
和 ry
属性,使其更加圆润。
原始配置:
1 | <rect id="terminalui" class="background" width="100%" height="100%" ry="4.5826941"/> |
修改后:
1 | <rect id="terminalui" class="background" width="100%" height="100%" rx="10" ry="10"/> |
设置快捷方式
通过 alias
配置默认启动参数,举个例子:
1 | # 先保存模板 |
需要时运行 termrec my_session_mac.svg
即可。
SVG 转 GIF
有时候,我们可能希望将 SVG 动画转换为更通用的 GIF 格式,以便在更多平台上展示(比如 CSDN)。这可以通过借助图像处理工具 ImageMagick
来实现。以下是详细步骤:
安装 ImageMagick
(实测存在问题,TODO)
ImageMagick
是一款强大的图像处理工具,支持多种格式的转换,包括 SVG 到 GIF。
-
在 Ubuntu 上,通过以下命令安装:
1
sudo apt-get install imagemagick
-
在 Mac上,使用 Homebrew 进行安装:
1
brew install imagemagick
使用 ImageMagick 转换 SVG 为 GIF
ImageMagick
安装完成后,可以使用 convert
命令将 SVG 文件转换为 GIF。
1 | convert -delay 20 -loop 0 my_animation.svg my_animation.gif |
其中 -delay 20
控制每帧之间的时间间隔(单位是1/100秒),-loop 0
指定 GIF 动画循环播放的次数(0表示无限循环)。
注意事项
-
转换质量:SVG动画的转换质量可能受多种因素影响,包括SVG的复杂度、转换参数等。可能需要调整
convert
命令的参数来优化输出的 GIF。 -
性能问题:如果SVG动画过于复杂,转换为GIF时可能会出现性能问题。可以考虑简化 SVG 内容或优化转换参数以提升性能。
以上,这些方法可以帮助你轻松将终端内容录制为 SVG 动画,或者更通用的 GIF 格式,便于在更多平台上展示。