Go bindings for libgd, targeting modern Go and libgd 2.3.x.
This branch is a breaking v2 rewrite. The module path is:
go get github.com/bolknote/go-gd/v2The public package lives in pkg/gd:
import gd "github.com/bolknote/go-gd/v2/pkg/gd"- Go 1.22 or newer
- cgo enabled
- libgd 2.3.x headers and library installed
On macOS with Homebrew:
brew install gdOn Debian/Ubuntu:
sudo apt-get install libgd-devThe bindings prefer a normal system libgd installation. Advanced formats depend on how libgd was built: AVIF, HEIF, TIFF, WebP, FreeType, FontConfig, RAQM, and libimagequant may not be available in every package.
package main
import gd "github.com/bolknote/go-gd/v2/pkg/gd"
func main() {
img, err := gd.NewTrueColor(320, 180)
if err != nil {
panic(err)
}
defer img.Close()
white, err := img.AllocateColor(255, 255, 255)
if err != nil {
panic(err)
}
black, err := img.AllocateColor(0, 0, 0)
if err != nil {
panic(err)
}
if err := img.Fill(0, 0, white); err != nil {
panic(err)
}
if err := img.Line(0, 0, img.Width()-1, img.Height()-1, black); err != nil {
panic(err)
}
if err := img.EncodePNGFile("out.png", nil); err != nil {
panic(err)
}
}Runnable examples live under examples/:
go run ./examples/basicv2 replaces the old PHP-style API with Go-style methods:
- Decode functions return
(*Image, error). - Encode functions return
erroror([]byte, error). Image.Close()releases the underlyinggdImagePtr.Destroy()is kept as a deprecated alias for v1 compatibility.- Colors use
ColorandRGBAvalue types instead ofmap[string]int. - Format-specific options use structs such as
JPEGOptions,PNGOptions,WebPOptions,HEIFOptions, andAVIFOptions. - Built-in bitmap text APIs draw Latin-1 strings. Use the FreeType APIs (
StringFT,StringFTEx) with a.ttffont path for UTF-8 text.
*Image and *IOContext values are not safe for concurrent use by multiple goroutines without external synchronization. Each value can be used by one goroutine at a time, including its Close call.
SetErrorMethodDiscard, ClearErrorMethod, UseFontConfig, and the FontCache* helpers manipulate libgd's process-global state.
For pipes, sockets, and arbitrary io.Writer/io.Reader-like sinks, use IOContext:
ctx, err := gd.NewDynamicWriteContext()
if err != nil {
panic(err)
}
if err := img.EncodePNGContext(ctx, nil); err != nil {
panic(err)
}
data, err := ctx.Extract()NewFileContext(path, mode) wraps a C FILE* and is the only way to encode XBM through libgd; the convenience helpers EncodeXBM/EncodeXBMFile build on top of it.
Use the linked libgd runtime information before enabling optional formats:
version := gd.Version()
features := gd.RuntimeFeatures()
_ = version.String
_ = features.WebPFor a single format:
if gd.SupportsFormat(gd.FormatAVIF, false) {
// AVIF decode is available in this libgd build.
}The v2 package tracks public BGD_DECLARE symbols from gd.h and gdfx.h.
Every public symbol must be either wrapped by the Go package or explicitly
documented as an internal/deprecated/unsafe exclusion in the API coverage test.
The v2 package wraps the libgd 2.3.x surface:
- Image lifecycle, dimensions, clone, resolution, clipping
- PNG, JPEG, GIF, WebP, WBMP, BMP, TGA, TIFF, GD/GD2, HEIF, AVIF, XBM, XPM
- Buffer, file, and
gdIOCtxencode/decode APIs - Drawing primitives, polygons, styles, brushes, tiles, alpha handling
- Palette and truecolor helpers, quantization, color replace/match
- Copy, resize, resample, rotate, scale, flip, interpolation and affine transforms
- Native libgd filters, effects, and
gdfx.h - Crop and compare APIs
- Built-in bitmap fonts and FreeType text rendering
- GIF animation buffer, file, and context APIs
- Version and feature probes
- Deprecated source/sink compatibility APIs are intentionally excluded; use
gdIOCtx.
Run:
make checkmake check lists the linked libgd API, runs the coverage audit through go test, and runs go vet.
Tests skip optional paths when the linked libgd does not support a feature. JPEG byte-for-byte golden tests are intentionally avoided because compression output can vary between libgd builds.
Run:
make analyzemake analyze runs go vet and golangci-lint.
The project intentionally relies on golangci-lint as the single lint runner; checks such as staticcheck, errcheck, ineffassign, and revive are enabled via .golangci.yml.
gosec is not part of the default flow for this CLI-focused project to avoid noisy reports.
The root contains project metadata only. The library package is under pkg/gd, examples are under examples/, and image fixtures are under testdata/.
The rewrite intentionally breaks old names:
CreateTrueColor->NewTrueColorCreateFromJpeg->DecodeJPEGFileImageToJpegBuffer->EncodeJPEGSx/Sy->Width/HeightJpeg,Png,Gif,Webp->EncodeJPEGFile,EncodePNGFile,EncodeGIFFile,EncodeWebPFileColorsForIndex->ColorRGBA
The old gdcompat.go helpers were removed from the core package. Native libgd filters replace grayscale, brightness, contrast, convolution, gaussian blur, emboss, edge detect, mean removal, smoothing, color adjustment, and negation. Non-libgd helpers such as font directory scanning, stack blur, and custom smooth ellipse drawing are no longer part of the core API.