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)或将字体转换为轮廓。

Canvas

主要特性

通用功能

  • 路径段类型:MoveTo、LineTo、QuadTo、CubeTo、ArcTo、Close
  • 精确的路径展平、描边和虚线绘制
  • 通过点生成平滑样条曲线(开放和闭合路径)
  • LaTeX到路径的转换
  • sRGB合规性

渲染目标

路径可以导出或渲染为:

  • 光栅图像(PNG、GIF、JPEG、TIFF、BMP、WEBP、AVIF等)
  • PDF
  • 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许可证。

Preview

Canvas库提供了强大的矢量图形处理能力,可以满足从简单的图形绘制到复杂的文档生成等各种需求。通过上述示例,您可以快速开始使用这个库来创建和导出各种格式的图形。


更多关于golang矢量图形转PDF/SVG/光栅图像处理插件库canvas的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于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))

性能优化技巧

  1. 复用对象:尽可能复用路径、渐变等对象
  2. 批量绘制:将多个小路径合并为一个大路径
  3. 合理使用变换:减少不必要的状态保存和恢复
  4. 选择合适的分辨率:输出光栅图像时不要使用过高的DPI

canvas 库功能强大且灵活,适合生成高质量的矢量图形和文档。通过组合基本图形、文本和高级效果,可以创建复杂的可视化内容。

回到顶部