golang矢量图形转PDF/SVG/光栅图像处理插件库canvas的使用
Golang矢量图形转PDF/SVG/光栅图像处理插件库canvas的使用
Canvas是一个通用的矢量绘图库,可以将图形输出为SVG、PDF、EPS、光栅图像(PNG、JPG、GIF等)、HTML Canvas(通过WASM)、OpenGL和Gio格式。它实现了丰富的路径操作功能,如路径展平、描边和虚线绘制等。此外,它还包含文本格式化功能,可以嵌入和子集化字体(TTF、OTF、WOFF、WOFF2或EOT)或将字体转换为轮廓。
主要特性
通用功能
- 路径段类型:MoveTo、LineTo、QuadTo、CubeTo、ArcTo、Close
- 精确的路径展平、描边和虚线绘制
- 通过点生成平滑样条曲线(开放和闭合路径)
- LaTeX到路径的转换
- sRGB合规性
渲染目标
路径可以导出或渲染为:
- 光栅图像(PNG、GIF、JPEG、TIFF、BMP、WEBP、AVIF等)
- SVG和SVGZ
- PS和EPS
- HTMLCanvas
- OpenGL
- Gio
- Fyne
示例代码
下面是一个简单的示例,展示如何使用canvas库创建一个简单的图形并导出为PDF和PNG:
package main
import (
"os"
"github.com/tdewolff/canvas"
"github.com/tdewolff/canvas/renderers"
)
func main() {
// 创建一个新的画布,大小为400x300
c := canvas.New(400, 300)
// 获取画布的上下文
ctx := canvas.NewContext(c)
// 设置填充颜色为蓝色
ctx.SetFillColor(canvas.Blue)
// 绘制一个矩形
ctx.DrawPath(100, 100, canvas.Rectangle(200, 100))
// 设置描边颜色为红色,线宽为5
ctx.SetStrokeColor(canvas.Red)
ctx.SetStrokeWidth(5)
// 绘制一个圆形
ctx.DrawPath(200, 200, canvas.Circle(50))
// 设置字体和文本颜色
face := canvas.NewFontFamily("times")
face.Use(canvas.CommonLigatures)
if err := face.LoadLocalFont("NimbusRoman-Regular", canvas.FontRegular); err != nil {
panic(err)
}
ctx.SetFillColor(canvas.Black)
// 绘制文本
text := canvas.NewTextLine(face.Face(20.0, canvas.Black), "Hello, Canvas!", canvas.Left)
ctx.DrawText(150, 50, text)
// 导出为PDF
pdfFile, err := os.Create("output.pdf")
if err != nil {
panic(err)
}
defer pdfFile.Close()
if err := renderers.Write(pdfFile, c); err != nil {
panic(err)
}
// 导出为PNG
pngFile, err := os.Create("output.png")
if err != nil {
panic(err)
}
defer pngFile.Close()
if err := renderers.Write(pngFile, c, canvas.DPMM(5.0)); err != nil {
panic(err)
}
}
高级文本渲染
Canvas支持高质量的文本渲染和换行,使用HarfBuzz进行文本整形,FriBidi进行文本双向处理,并使用Donald Knuth的换行算法进行文本布局:
func drawTextExample(ctx *canvas.Context) {
// 创建字体家族
family := canvas.NewFontFamily("latin")
if err := family.LoadLocalFont("Arial", canvas.FontRegular); err != nil {
panic(err)
}
// 创建富文本(可以混合不同样式)
richText := canvas.NewRichText()
richText.Add(family.Face(24.0, canvas.Black), "Hello, ")
richText.Add(family.Face(24.0, canvas.Black, canvas.FontBold), "World!")
// 在指定矩形内绘制文本(自动换行和调整)
textBox := richText.ToText(200.0, 100.0, canvas.Justify, canvas.Top, 0.0, 0.0)
ctx.DrawText(100.0, 200.0, textBox)
}
路径操作示例
Canvas提供了强大的路径操作功能:
func pathOperationsExample(ctx *canvas.Context) {
// 创建一个复杂路径
path := canvas.NewPath()
path.MoveTo(50, 50)
path.LineTo(150, 50)
path.QuadTo(200, 100, 150, 150)
path.CubeTo(125, 175, 75, 175, 50, 150)
path.Close()
// 设置填充和描边样式
ctx.SetFillColor(canvas.Lightblue)
ctx.SetStrokeColor(canvas.Black)
ctx.SetStrokeWidth(3.0)
// 绘制路径
ctx.DrawPath(100, 100, path)
// 路径布尔运算示例
path1 := canvas.Rectangle(100, 100)
path2 := canvas.Circle(50).Translate(50, 50)
// 并集
union := path1.Or(path2)
ctx.SetFillColor(canvas.Red)
ctx.DrawPath(200, 100, union)
// 交集
intersection := path1.And(path2)
ctx.SetFillColor(canvas.Green)
ctx.DrawPath(300, 100, intersection)
}
状态
该库是否适合生产环境取决于您自己的判断。一般来说,这个库编写得很周到且完整,但由于工作范围很大,实现可能相当复杂,不可避免地会有大量错误。已经投入了大量精力编写单元和模糊测试,但覆盖率仍然不足。
许可证
该库在MIT许可证下发布。需要注意的是,Fribidi使用LGPL许可证。
Canvas库提供了强大的矢量图形处理能力,可以满足从简单的图形绘制到复杂的文档生成等各种需求。通过上述示例,您可以快速开始使用这个库来创建和导出各种格式的图形。
更多关于golang矢量图形转PDF/SVG/光栅图像处理插件库canvas的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang矢量图形转PDF/SVG/光栅图像处理插件库canvas的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Golang 矢量图形处理库 canvas 使用指南
canvas 是一个功能强大的 Golang 矢量图形处理库,可以用于创建和转换矢量图形到 PDF、SVG 以及各种光栅图像格式。下面我将详细介绍它的主要功能和使用方法。
安装
首先安装 canvas 库:
go get github.com/tdewolff/canvas
基本使用
创建画布
package main
import (
"github.com/tdewolff/canvas"
"github.com/tdewolff/canvas/renderers"
)
func main() {
// 创建一个 400x300 的画布
c := canvas.New(400, 300)
// 获取绘图上下文
ctx := canvas.NewContext(c)
// 设置填充颜色并绘制矩形
ctx.SetFillColor(canvas.MustParseHex("#FF0000"))
ctx.DrawPath(100, 100, canvas.Rectangle(200, 100))
// 保存为PDF
renderers.Write("output.pdf", c)
}
输出格式支持
canvas 支持多种输出格式:
1. 输出为 PDF
renderers.Write("output.pdf", c)
2. 输出为 SVG
renderers.Write("output.svg", c)
3. 输出为光栅图像 (PNG, JPG等)
// 输出为PNG
renderers.Write("output.png", c, canvas.DPI(300))
// 输出为JPG
renderers.Write("output.jpg", c, canvas.DPI(300), canvas.JPEGQuality(90))
高级绘图功能
绘制文本
fontFamily := canvas.NewFontFamily("times")
if err := fontFamily.LoadLocalFont("Times New Roman", canvas.FontRegular); err != nil {
panic(err)
}
face := fontFamily.Face(24.0, canvas.Black, canvas.FontRegular, canvas.FontNormal)
ctx.DrawText(50, 200, canvas.NewTextLine(face, "Hello, World!", canvas.Left))
绘制路径和曲线
// 创建路径
path := &canvas.Path{}
path.MoveTo(50, 50)
path.LineTo(100, 100)
path.QuadTo(150, 150, 200, 100)
path.CubeTo(250, 50, 300, 150, 350, 100)
path.Close()
// 绘制路径
ctx.SetStrokeColor(canvas.Black)
ctx.SetStrokeWidth(2.0)
ctx.DrawPath(0, 0, path)
使用变换
// 平移
ctx.Push()
ctx.Translate(100, 50)
ctx.DrawPath(0, 0, canvas.Rectangle(50, 50))
ctx.Pop()
// 旋转
ctx.Push()
ctx.Rotate(45)
ctx.DrawPath(100, 100, canvas.Rectangle(50, 50))
ctx.Pop()
// 缩放
ctx.Push()
ctx.Scale(2.0, 0.5)
ctx.DrawPath(200, 200, canvas.Rectangle(50, 50))
ctx.Pop()
高级特性
使用渐变和图案
// 线性渐变
gradient := canvas.NewLinearGradient(100, 100, 200, 200)
gradient.AddColorStop(0.0, canvas.MustParseHex("#FF0000"))
gradient.AddColorStop(1.0, canvas.MustParseHex("#0000FF"))
ctx.SetFillGradient(gradient)
ctx.DrawPath(100, 100, canvas.Rectangle(100, 100))
// 径向渐变
radialGradient := canvas.NewRadialGradient(150, 150, 0, 150, 150, 50)
radialGradient.AddColorStop(0.0, canvas.MustParseHex("#FFFFFF"))
radialGradient.AddColorStop(1.0, canvas.MustParseHex("#000000"))
ctx.SetFillGradient(radialGradient)
ctx.DrawPath(100, 100, canvas.Circle(50))
使用图案
// 创建图案
patternCanvas := canvas.New(20, 20)
patternCtx := canvas.NewContext(patternCanvas)
patternCtx.SetFillColor(canvas.MustParseHex("#FF0000"))
patternCtx.DrawPath(0, 0, canvas.Rectangle(10, 10))
patternCtx.SetFillColor(canvas.MustParseHex("#00FF00"))
patternCtx.DrawPath(10, 10, canvas.Rectangle(10, 10))
pattern := canvas.NewPattern(patternCanvas, canvas.RepeatBoth, canvas.Identity.Translate(0, 0))
ctx.SetFillPattern(pattern)
ctx.DrawPath(0, 0, canvas.Rectangle(400, 300))
性能优化技巧
- 复用对象:尽可能复用路径、渐变等对象
- 批量绘制:将多个小路径合并为一个大路径
- 合理使用变换:减少不必要的状态保存和恢复
- 选择合适的分辨率:输出光栅图像时不要使用过高的DPI
canvas 库功能强大且灵活,适合生成高质量的矢量图形和文档。通过组合基本图形、文本和高级效果,可以创建复杂的可视化内容。