Here are 4 examples of data-driven graphics generation in Go, covering raster (PNG), programmatic vector (SVG), and design-first vector templating (Illustrator/Inkscape workflow).
These examples use the following popular libraries:
go get -u github.com/fogleman/gg (For Raster/PNG)go get -u github.com/ajstarks/svgo (For Programmatic SVG)fogleman/gg)This method is best for creating social media cards, certificates, or badges where pixel-perfect text layout on top of a specific background image is required. It treats the graphic as a canvas.
File: generate_certificate.go
package main
import (
"fmt"
"image/color"
"log"
"github.com/fogleman/gg"
)
type CertificateData struct {
Name string
Course string
AvatarPath string
}
func main() {
// 1. Data Source
data := CertificateData{
Name: "Alice Engineer",
Course: "Advanced Golang Graphics",
AvatarPath: "avatar.png", // Ensure this file exists
}
// 2. Load Base Template (Background Image)
// In a real app, load "background.png". Here we create a blank one for the demo.
dc := gg.NewContext(800, 600)
dc.SetColor(color.White)
dc.Clear()
// Draw a border to simulate a template
dc.SetColor(color.RGBA{50, 50, 150, 255})
dc.SetLineWidth(20)
dc.DrawRectangle(0, 0, 800, 600)
dc.Stroke()
// 3. Load and Draw User Picture (Dynamic Image)
// We verify the file exists in a real scenario.
if avatar, err := gg.LoadImage(data.AvatarPath); err == nil {
// Resize and draw avatar at specific coordinates
dc.DrawImage(avatar, 50, 50)
}
// 4. Draw Dynamic Text
// Load a font (You must have a .ttf file, or use basic font installation)
// err := dc.LoadFontFace("/Library/Fonts/Arial.ttf", 48)
// if err != nil { log.Fatal(err) }
// Drawing Name (Centered)
dc.SetRGB(0, 0, 0)
dc.DrawStringAnchored(data.Name, 400, 300, 0.5, 0.5)
// Drawing Course Title
dc.SetRGB(0.2, 0.2, 0.2)
dc.DrawStringAnchored("Completed: "+data.Course, 400, 380, 0.5, 0.5)
// 5. Save Result
if err := dc.SavePNG("output_certificate.png"); err != nil {
log.Fatal(err)
}
fmt.Println("Certificate generated successfully.")
}
ajstarks/svgo)This is the "Normal Way" to generate SVG. You define the shapes and text coordinates in code. It is excellent for data visualizations, charts, or diagrams where layout depends heavily on the data values.
File: generate_chart.go
package main
import (
"os"
svg "github.com/ajstarks/svgo"
)
func main() {
// 1. Setup Output File
file, err := os.Create("output_chart.svg")
if err != nil {
panic(err)
}
defer file.Close()
// 2. Initialize Canvas
width, height := 500, 500
canvas := svg.New(file)
canvas.Start(width, height)
// 3. Data Source
data := []struct {
Label string
Value int
Color string
}{
{"Q1", 50, "red"},
{"Q2", 80, "blue"},
{"Q3", 45, "green"},
{"Q4", 95, "orange"},
}
// 4. Draw Background
canvas.Rect(0, 0, width, height, "fill:white;stroke:black")
canvas.Text(250, 30, "Quarterly Performance", "text-anchor:middle;font-size:24px")
// 5. Loop through Data to Draw Graphics
barWidth := 80
gap := 20
startX := 50
for i, d := range data {
x := startX + (i * (barWidth + gap))
// Coordinate system: Y increases downwards, so we flip the height math
barHeight := d.Value * 3
y := 400 - barHeight
// Draw Bar
canvas.Rect(x, y, barWidth, barHeight, "fill:"+d.Color)
// Draw Label
canvas.Text(x+barWidth/2, 420, d.Label, "text-anchor:middle")
// Draw Value
canvas.Text(x+barWidth/2, y-10, fmt.Sprintf("%d", d.Value), "text-anchor:middle")
}
// 6. Embed an External Image (Logo)
// href can be a local path or URL
canvas.Image(400, 450, 50, 50, "logo.png")
canvas.End()
}
text/template)This is the most powerful workflow for designers.
{{.Title}}. Where you want a dynamic image, set the href to {{.ImageURL}}.