gg
Before You Start
- Applies to: Go 1.21+ (examples verified with Go 1.22) · Prerequisites: Base: Structs · Read time: about 12 min
Official Repository: fogleman/gg: Go Graphics - 2D rendering in Go with a simple API. (github.com)
Official Documentation: gg package - github.com/fogleman/gg - Go Packages
Official Examples: gg/examples at master · fogleman/gg (github.com)
gg is a well-established 2D graphics rendering engine, suitable for generating images.
Installation
go get -u github.com/fogleman/ggQuick Start
go
package main
import "github.com/fogleman/gg"
func main() {
dc := gg.NewContext(1000, 1000) // Create canvas, height 1000, width 1000
dc.DrawCircle(500, 500, 400) // Draw a circle with radius 400 at coordinates (500,500)
dc.SetRGB(0, 0, 0) // Set color to black
dc.Fill() // Fill
dc.SavePNG("out.png") // Save to image file
}Points

go
func TestDot(t *testing.T) {
dc := gg.NewContext(1000, 1000)
dc.SetRGB(0, 0, 0)
for i := 1; i < 10; i++ {
dc.DrawPoint(float64(50*i), float64(50*i), 5) // Set point coordinates and radius
}
dc.Fill() // Fill
dc.SavePNG("out.png")
}Lines

go
func TestLines(t *testing.T) {
dc := gg.NewContext(1000, 1000)
dc.SetRGB(0, 0, 0)
dc.SetLineWidth(5) // Set line width
dc.DrawLine(1000, 0, 0, 1000)
dc.DrawLine(1000, 1000, 0, 0)
dc.Stroke() // Draw lines
dc.SavePNG("lines.png")
}Complete Example
The program below runs as-is: copy it into a file and execute go run main.go, or paste it into the Go Playground.
go
package main
import "fmt"
func main() {
// A 5x3 canvas with a diagonal line, standing in for a gg context
const w, h = 5, 3
canvas := make([][]bool, h)
for i := range canvas {
canvas[i] = make([]bool, w)
}
for i := 0; i < h; i++ {
canvas[i][i] = true
}
for _, row := range canvas {
line := ""
for _, on := range row {
if on {
line += "#"
} else {
line += "."
}
}
fmt.Println(line)
}
}Expected output:
text
#....
.#...
..#..Common Pitfalls
- Remember to stroke or fill. Drawing commands only take effect after
Stroke()/Fill(). - Save with the right format.
SavePNGandSaveJPGdiffer in quality and alpha support. - Fonts need a path.
LoadFontFacerequires a TTF file; there is no system font fallback. - Contexts are not concurrency-safe. Draw on one goroutine or synchronise access.
- Large canvases cost memory. Width×height×4 bytes adds up; reuse buffers when rendering frames.
Change Log
- 2026-10-14: Added "Before You Start" notes, a complete runnable example with expected output, common pitfalls, and this change log. Closed a code block that was left unterminated.
