# Image Renderer
[](https://opensource.org/licenses/MIT)
[](https://www.rust-lang.org/)
一个功能完整的 Rust 图像处理库,参考 Skia API 风格设计,提供简洁易用的 2D 图形绘制能力。
## ✨ 主要特性
- 🎨 **丰富的绘图功能**
- 基本图形:矩形、圆形、椭圆、线条
- 圆角矩形、自定义边框
- 虚线样式支持(短虚线、长虚线、点状、点划线等)
- 🛤️ **路径系统(Path)**
- 支持复杂矢量图形绘制
- 贝塞尔曲线(二次、三次)
- 圆弧、直线、闭合路径
- 路径填充规则(Winding、EvenOdd)
- 🔄 **变换系统(Transform)**
- 2D 仿射变换矩阵
- 平移、缩放、旋转
- 变换组合和状态管理
- save/restore 状态栈
- ✂️ **裁剪系统(Clipping)**
- 矩形裁剪
- 路径裁剪
- 裁剪操作(交集、差集)
- 多层裁剪支持
- 📝 **文本渲染**
- 支持系统字体和自定义字体
- 可调节字体大小、颜色
- 支持加粗、斜体样式
- 🖼️ **图像处理**
- 图片加载与保存(PNG、JPEG)
- 九宫格(Nine-Patch)图片绘制
- 图像变换和渲染
- 🎯 **高性能**
- Release 模式下启用 LTO 优化
- 零成本抽象设计
- 高效的内存管理
## 📦 安装
在 `Cargo.toml` 中添加依赖:
```toml
[dependencies]
image-renderer = "0.1.0"
```
## 🚀 快速开始
### 基础绘制示例
```rust
use image_renderer::{Canvas, Color, Paint, Point, Rect, Font, TextStyle};
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 创建 800x600 的画布,白色背景
let mut canvas = Canvas::new_with_color(800, 600, Color::WHITE)?;
// 绘制填充矩形
let rect = Rect::new(100, 100, 200, 150);
let paint = Paint::fill(Color::BLUE);
canvas.draw_rect(rect, &paint);
// 绘制描边圆形
let center = Point::new(400, 300);
let paint_stroke = Paint::stroke(Color::RED, 3.0);
canvas.draw_circle(center, 80.0, &paint_stroke);
// 绘制文本
let font = Font::default_system_font()?;
let text_style = TextStyle::new(font, 24.0);
let mut paint_text = Paint::new();
paint_text.set_color(Color::BLACK);
canvas.draw_text("Hello, World!", Point::new(100, 50), &text_style, &paint_text);
// 保存图片
canvas.save("output.png")?;
Ok(())
}
```
### 虚线绘制
```rust
use image_renderer::{Canvas, Color, Paint, Point, DashStyle};
let mut canvas = Canvas::new_with_color(800, 600, Color::WHITE)?;
// 创建虚线画笔
let mut paint = Paint::stroke(Color::BLUE, 2.0);
paint.set_dash_style(DashStyle::ShortDash);
// 绘制虚线
canvas.draw_dashed_line(Point::new(50, 100), Point::new(750, 100), &paint);
canvas.save("dashed_line.png")?;
```
### 九宫格图片绘制
```rust
use image_renderer::{Canvas, Color, Rect, Surface};
// 加载源图片
let source_image = Surface::from_file("button.png")?;
// 创建画布
let mut canvas = Canvas::new_with_color(800, 600, Color::WHITE)?;
// 定义九宫格的中心区域(保留边缘 20 像素)
let center = Rect::new(20, 20, 60, 60);
// 绘制到目标区域(会自动拉伸)
let dst = Rect::new(50, 50, 300, 150);
canvas.draw_image_nine(&source_image, center, dst)?;
canvas.save("nine_patch_output.png")?;
```
### 自定义边框
```rust
use image_renderer::{Canvas, Color, Paint, Rect, Border, BorderSide, BorderRadius};
let mut canvas = Canvas::new_with_color(800, 600, Color::WHITE)?;
// 创建自定义边框
let border = Border {
top: BorderSide::new(Color::RED, 5.0),
right: BorderSide::new(Color::GREEN, 3.0),
bottom: BorderSide::new(Color::BLUE, 5.0),
left: BorderSide::new(Color::YELLOW, 3.0),
};
let radius = BorderRadius {
top_left: 20.0,
top_right: 10.0,
bottom_right: 20.0,
bottom_left: 10.0,
};
let rect = Rect::new(100, 100, 300, 200);
let paint = Paint::fill(Color::WHITE);
canvas.draw_rect_with_border(rect, &paint, &border, &radius);
canvas.save_to_file("custom_border.png")?;
```
### 路径绘制
```rust
use image_renderer::{Canvas, Color, Paint, Path, PathDirection};
let mut canvas = Canvas::new_with_color(800, 600, Color::WHITE)?;
// 创建路径
let mut path = Path::new();
path.move_to((100.0, 100.0));
path.line_to((200.0, 100.0));
path.quad_to((250.0, 150.0), (200.0, 200.0));
path.cubic_to((150.0, 250.0), (100.0, 250.0), (100.0, 200.0));
path.close();
// 绘制路径
let paint = Paint::fill(Color::BLUE);
canvas.draw_path(&path, &paint);
canvas.save_to_file("path_output.png")?;
```
### 变换操作
```rust
use image_renderer::{Canvas, Color, Paint, Rect};
let mut canvas = Canvas::new_with_color(800, 600, Color::WHITE)?;
let rect = Rect::new(0, 0, 100, 100);
let paint = Paint::fill(Color::RED);
// 保存状态
canvas.save();
// 应用变换
canvas.translate(200.0, 200.0);
canvas.rotate(45.0);
canvas.scale(1.5, 1.5);
// 绘制
canvas.draw_rect(rect, &paint);
// 恢复状态
canvas.restore();
canvas.save_to_file("transform_output.png")?;
```
### 裁剪操作
```rust
use image_renderer::{Canvas, ClipOp, Color, Paint, Point, Rect};
let mut canvas = Canvas::new_with_color(800, 600, Color::WHITE)?;
// 设置裁剪区域
let clip_rect = Rect::new(100, 100, 200, 200);
canvas.save();
canvas.clip_rect(clip_rect, ClipOp::Intersect);
// 绘制(只有裁剪区域内的部分会显示)
let paint = Paint::fill(Color::BLUE);
canvas.draw_circle(Point::new(200, 200), 150.0, &paint);
canvas.restore();
canvas.save_to_file("clip_output.png")?;
```
## 📚 核心 API
### Canvas(画布)
```rust
// 创建画布
let canvas = Canvas::new(800, 600)?;
let canvas = Canvas::new_with_color(800, 600, Color::WHITE)?;
// 清空画布
canvas.clear(Color::WHITE);
// 保存图片
canvas.save_to_file("output.png")?;
// 状态管理
canvas.save(); // 保存当前状态
canvas.restore(); // 恢复之前的状态
```
### Paint(画笔)
```rust
// 创建填充画笔
let paint = Paint::fill(Color::BLUE);
// 创建描边画笔
let paint = Paint::stroke(Color::RED, 3.0);
// 设置虚线样式
paint.set_dash_style(DashStyle::ShortDash);
```
### Color(颜色)
```rust
// 预定义颜色
Color::RED
Color::GREEN
Color::BLUE
Color::WHITE
Color::BLACK
// RGB 创建
Color::rgb(255, 0, 0)
// RGBA 创建
Color::rgba(255, 0, 0, 128)
// 十六进制创建
Color::from_hex("#FF0000")?
Color::from_hex("#FF0000FF")?
```
### 绘图方法
```rust
// 绘制矩形
canvas.draw_rect(rect, &paint);
canvas.draw_rounded_rect(rect, radius, &paint);
// 绘制圆形和椭圆
canvas.draw_circle(center, radius, &paint);
canvas.draw_oval(rect, &paint);
// 绘制线条
canvas.draw_line(start, end, &paint);
canvas.draw_dashed_line(start, end, &paint);
// 绘制路径
canvas.draw_path(&path, &paint);
// 绘制文本
canvas.draw_text(text, position, &text_style, &paint);
// 绘制图片
canvas.draw_image(&surface, dst_rect)?;
canvas.draw_image_nine(&surface, center, dst_rect)?;
```
### 变换方法
```rust
// 平移
canvas.translate(dx, dy);
// 缩放
canvas.scale(sx, sy);
// 旋转(角度)
canvas.rotate(degrees);
canvas.rotate_around(degrees, px, py);
// 重置变换
canvas.reset_matrix();
// 设置变换矩阵
canvas.set_matrix(&matrix);
canvas.concat(&matrix);
```
### 裁剪方法
```rust
// 矩形裁剪
canvas.clip_rect(rect, ClipOp::Intersect);
// 路径裁剪
canvas.clip_path(&path, ClipOp::Intersect);
// 获取裁剪边界
let bounds = canvas.get_clip_bounds();
```
## 🎨 虚线样式
支持多种虚线样式:
- `DashStyle::Solid` - 实线
- `DashStyle::ShortDash` - 短虚线
- `DashStyle::LongDash` - 长虚线
- `DashStyle::Dot` - 点状
- `DashStyle::DashDot` - 点划线
- `DashStyle::DashDotDot` - 双点划线
- `DashStyle::Custom(Vec<f32>)` - 自定义模式
## 🔧 运行示例
项目包含完整的示例程序,展示了所有主要功能:
```bash
# 运行主程序(包含所有基础示例)
cargo run
# 运行路径绘制示例
cargo run --example path_drawing
# 运行变换示例
cargo run --example transform
# 运行裁剪示例
cargo run --example clipping
# 运行测试
cargo test
# 构建 Release 版本
cargo build --release
```
运行后会生成以下示例图片:
- `output_basic.png` - 基础绘制示例
- `output_nine_patch.png` - 九宫格绘制示例
- `output_dashed_lines.png` - 虚线样式示例
- `output_custom_borders.png` - 自定义边框示例
- `output_path_drawing.png` - 路径绘制示例
- `output_transform.png` - 变换操作示例
- `output_clipping.png` - 裁剪操作示例
## 🎓 学习资源
### 示例代码
- **基础绘制**: 查看 `src/main.rs` 了解基本绘图功能
- **路径绘制**: 查看 `examples/path_drawing.rs` 学习如何绘制复杂矢量图形
- **变换操作**: 查看 `examples/transform.rs` 学习 2D 变换
- **裁剪功能**: 查看 `examples/clipping.rs` 学习裁剪技术
### API 特性对比
本库参考 skia-safe API 设计,提供了以下核心功能:
| 基础图形 | ✅ | ✅ | 矩形、圆形、椭圆等 |
| 路径系统 | ✅ | ✅ | Path、贝塞尔曲线 |
| 变换矩阵 | ✅ | ✅ | 平移、缩放、旋转 |
| 裁剪系统 | ✅ | ✅ | 矩形和路径裁剪 |
| 状态管理 | ✅ | ✅ | save/restore |
| 文本渲染 | ✅ | ✅ | 字体、样式 |
| 图片处理 | ✅ | ✅ | 加载、保存、变换 |
| 虚线样式 | ✅ | ✅ | 多种虚线模式 |
| 渐变填充 | ✅ | 🚧 | 计划中 |
| 阴影效果 | ✅ | 🚧 | 计划中 |
## 📖 文档
查看完整的 API 文档:
```bash
cargo doc --open
```
## 🛠️ 技术栈
- **图像处理**: [image](https://crates.io/crates/image) - 图片编解码
- **图像操作**: [imageproc](https://crates.io/crates/imageproc) - 图像处理算法
- **字体渲染**: [rusttype](https://crates.io/crates/rusttype) + [font-kit](https://crates.io/crates/font-kit)
- **错误处理**: [thiserror](https://crates.io/crates/thiserror) + [anyhow](https://crates.io/crates/anyhow)
- **日志**: [tracing](https://crates.io/crates/tracing)
## 🤝 贡献
欢迎提交 Issue 和 Pull Request!
## 📄 许可证
本项目采用 MIT 许可证 - 详见 [LICENSE](LICENSE) 文件
## 👤 作者
Jerry <jerry@jerry.moe>
## 🔗 相关链接
- [GitHub 仓库](https://github.com/jerryshew/image-renderer)
- [文档](https://docs.rs/image-renderer)
- [Crates.io](https://crates.io/crates/image-renderer)