Rust SVG处理库typst-svg的使用,高效解析与渲染矢量图形的轻量级解决方案
Rust SVG处理库typst-svg的使用,高效解析与渲染矢量图形的轻量级解决方案
Typst是一个基于标记的排版系统,设计目标是拥有LaTeX的强大功能,同时更易于学习和使用。Typst具有以下特点:
- 内置常见格式化任务的标记语法
- 灵活的脚本系统
- 数学公式排版、参考文献管理等
- 增量编译带来的快速编译速度
- 出错时提供友好的错误信息
安装
可以通过以下方式安装Typst:
- 从GitHub releases页面下载预编译二进制文件
- 使用包管理器:
- macOS:
brew install typst
- Windows:
winget install --id Typst.Typst
- macOS:
- 使用Rust工具链:
cargo install --locked typst-cli
使用示例
以下是Typst的一个完整示例代码:
// 设置页面大小和标题编号
#set page(width: 10cm, height: auto)
#set heading(numbering: "1.")
= Fibonacci sequence
The Fibonacci sequence is defined through the
recurrence relation $F_n = F_(n-1) + F_(n-2)$.
It can also be expressed in _closed form:_
$ F_n = round(1 / sqrt(5) phi.alt^n), quad
phi.alt = (1 + sqrt(5)) / 2 $
// 定义变量和函数
#let count = 8
#let nums = range(1, count + 1)
#let fib(n) = (
if n <= 2 { 1 }
else { fib(n - 1) + fib(n - 2) }
)
// 显示结果表格
The first #count numbers of the sequence are:
#align(center, table(
columns: count,
..nums.map(n => $F_#n$),
..nums.map(n => str(fib(n))),
))
SVG处理示例
以下是使用typst-svg处理SVG的完整示例代码:
use typst_svg::{render, scale};
use usvg::Options;
// SVG内容
let svg_data = r#"
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="40" stroke="green" stroke-width="4" fill="yellow" />
</svg>
"#;
// 解析和渲染SVG
let tree = usvg::Tree::from_str(svg_data, &Options::default()).unwrap();
let pixmap_size = tree.size.to_screen_size();
let mut pixmap = tiny_skia::Pixmap::new(pixmap_size.width(), pixmap_size.height()).unwrap();
// 缩放SVG
let transform = scale(1.0, 1.0);
render(&tree, transform, &mut pixmap.as_mut());
// 输出PNG
pixmap.save_png("output.png").unwrap();
完整示例demo
以下是一个更完整的typst-svg使用示例,包含文件读取和错误处理:
use std::fs;
use std::path::Path;
use typst_svg::{render, scale};
use usvg::{Options, Tree};
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 1. 读取SVG文件内容
let svg_path = Path::new("input.svg");
let svg_data = fs::read_to_string(svg_path)?;
// 2. 配置解析选项
let options = Options {
// 设置资源路径
resources_dir: Some(svg_path.parent().unwrap().to_path_buf()),
// 设置默认字体
font_family: "Arial".to_string(),
..Options::default()
};
// 3. 解析SVG
let tree = Tree::from_str(&svg_data, &options)?;
// 4. 创建目标画布
let pixmap_size = tree.size.to_screen_size();
let mut pixmap = tiny_skia::Pixmap::new(
pixmap_size.width(),
pixmap_size.height()
).expect("Failed to create pixmap");
// 5. 渲染SVG到画布
let transform = scale(1.0, 1.0); // 不缩放
render(&tree, transform, &mut pixmap.as_mut());
// 6. 保存为PNG
let output_path = "output.png";
pixmap.save_png(output_path)?;
println!("SVG成功渲染并保存为 {}", output_path);
Ok(())
}
设计原则
Typst遵循三个核心设计原则:
- 通过一致性实现简单性:知识可以跨功能转移
- 通过可组合性实现强大功能:提供可以组合的系统
- 通过增量性实现性能:所有语言特性都支持增量编译
社区
Typst的主要社区在Discord服务器上,你可以在那里提问、分享作品或参与讨论。
Typst是一个强大的排版系统,结合typst-svg库可以高效处理SVG矢量图形,是轻量级的解决方案。
1 回复
Rust SVG处理库typst-svg的使用:高效解析与渲染矢量图形的轻量级解决方案
介绍
typst-svg是一个用于解析和渲染SVG(可缩放矢量图形)的轻量级Rust库。它专注于高效处理SVG文件,提供简洁的API来解析、修改和渲染矢量图形。该库特别适合需要嵌入SVG功能的应用程序,如文档生成器、图形编辑器或数据可视化工具。
主要特性
- 轻量级且高效,没有不必要的依赖
- 支持SVG规范的核心功能
- 提供简洁的API进行SVG操作
- 支持将SVG渲染为其他格式
- 良好的错误处理机制
完整示例代码
use typst_svg::{Svg, render::{render, render_to_png}, geom::Transform};
use std::fs;
fn main() {
// 示例1: 解析SVG文件
let svg_data = r#"
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="40" fill="red" />
</svg>
"#;
let svg = Svg::from_str(svg_data).expect("解析SVG失败");
println!("SVG尺寸: {:?}", svg.view_box());
// 示例2: 渲染SVG
let rendered = render(&svg, 1.0); // 缩放因子1.0
println!("渲染结果: {:?}", rendered);
// 示例3: 修改SVG元素
let mut svg = Svg::from_str(r#"
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
<rect id="myRect" x="10" y="10" width="80" height="80" fill="green" />
</svg>
"#).unwrap();
if let Some(rect) = svg.find_element_by_id("myRect") {
rect.set_transform(Transform::translate(5.0, 5.0)); // 平移变换
rect.set_attr("fill", "purple"); // 修改填充颜色
}
println!("修改后的SVG: {}", svg.to_string());
// 示例4: SVG转PNG
let png_data = render_to_png(&svg, 1.0).unwrap();
fs::write("output.png", png_data).unwrap();
// 示例5: 处理复杂SVG
let complex_svg = Svg::from_str(r#"
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color:rgb(255,255,0);stop-opacity:1" />
<stop offset="100%" style="stop-color:rgb(255,0,0);stop-opacity:1" />
</linearGradient>
</defs>
<rect x="50" y="50" width="100" height="100" fill="url(#grad1)" />
</svg>
"#).unwrap();
println!("复杂SVG元素: {:?}", complex_svg.elements());
// 示例6: 错误处理
match Svg::from_str("<svg>无效SVG</svg>") {
Ok(svg) => println!("SVG解析成功"),
Err(e) => eprintln!("SVG解析失败: {}", e),
}
}
性能提示
- 对于重复使用的SVG,考虑解析一次后缓存
Svg
实例 - 使用
render_with_scale
时选择合适的缩放因子以避免不必要的计算 - 对于大型SVG文件,考虑只加载需要的部分
总结
typst-svg是一个功能强大但保持简洁的SVG处理库,非常适合需要嵌入SVG功能的Rust应用程序。它的轻量级特性使其成为许多项目的理想选择。通过上述示例,您可以快速了解如何使用该库进行SVG的解析、渲染、修改和格式转换等操作。