SkillAgentSearch skills...

Vipsgen

Go binding generator for libvips image processing library

Install / Use

/learn @cshum/Vipsgen
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

vipsgen

Go Reference CI

vipsgen is a Go binding generator for libvips - a fast and efficient image processing library.

libvips is generally 4-8x faster than ImageMagick with low memory usage, thanks to its demand-driven, horizontally threaded architecture.

Existing Go libvips bindings rely on manually written code that is often incomplete, error-prone, and difficult to maintain as libvips evolves. vipsgen solves this by generating type-safe, robust, and fully documented Go bindings using GObject introspection.

  • Comprehensive: Bindings for around 300 libvips operations
  • Type-Safe: Proper Go types for all libvips C enums and structs
  • Idiomatic: Clean Go APIs that feel natural to use
  • Streaming: VipsSource and VipsTarget integration with Go io.Reader and io.Writer for streaming

You can use vipsgen in two ways:

  • Import directly: Use the pre-generated library github.com/cshum/vipsgen/vips for the latest default installation of libvips, or see pre-generated packages
  • Generate custom bindings: Run the vipsgen command to create bindings for your specific libvips version and installation

Quick Start

Use homebrew to install vips and pkg-config:

brew install vips pkg-config

On MacOS, vipsgen may not compile without first setting an environment variable:

export CGO_CFLAGS_ALLOW="-Xpreprocessor"

Use the package directly:

go get -u github.com/cshum/vipsgen/vips

All operations support parameters and optional arguments through structs, maintaining direct equivalence with the libvips API. Pass nil to use default behavior for optional arguments. See examples for common usage patterns.

package main

import (
	"log"
	"net/http"

	"github.com/cshum/vipsgen/vips"
)

func main() {
	// Fetch an image from http.Get
	resp, err := http.Get("https://raw.githubusercontent.com/cshum/imagor/master/testdata/gopher.png")
	if err != nil {
		log.Fatalf("Failed to fetch image: %v", err)
	}
	defer resp.Body.Close()

	// Create source from io.ReadCloser
	source := vips.NewSource(resp.Body)
	defer source.Close() // source needs to remain available during image lifetime

	// Shrink-on-load via creating image from thumbnail source with options
	image, err := vips.NewThumbnailSource(source, 800, &vips.ThumbnailSourceOptions{
		Height: 1000,
		FailOn: vips.FailOnError, // Fail on first error
	})
	if err != nil {
		log.Fatalf("Failed to load image: %v", err)
	}
	defer image.Close() // always close images to free memory

	// Add a yellow border using vips_embed
	border := 10
	if err := image.Embed(
		border, border,
		image.Width()+border*2,
		image.Height()+border*2,
		&vips.EmbedOptions{
			Extend:     vips.ExtendBackground,       // extend with colour from the background property
			Background: []float64{255, 255, 0, 255}, // Yellow border
		},
	); err != nil {
		log.Fatalf("Failed to add border: %v", err)
	}

	log.Printf("Processed image: %dx%d\n", image.Width(), image.Height())

	// Save the result as WebP file with options
	err = image.Webpsave("resized-gopher.webp", &vips.WebpsaveOptions{
		Q:              85,   // Quality factor (0-100)
		Effort:         4,    // Compression effort (0-6)
		SmartSubsample: true, // Better chroma subsampling
	})
	if err != nil {
		log.Fatalf("Failed to save image as WebP: %v", err)
	}
	log.Println("Successfully saved processed images")
}

Pre-generated Packages

vipsgen provides pre-generated bindings for the following libvips versions. All packages use the same vips package name and API - only the import path differs.

| Import Path | libvips Version | Use When | |-------------|----------------|----------| | github.com/cshum/vipsgen/vips | 8.18.0 | Latest version (recommended) | | github.com/cshum/vipsgen/vips817 | 8.17.3 | You have libvips 8.17.x installed | | github.com/cshum/vipsgen/vips816 | 8.16.1 | You have libvips 8.16.x installed |

Important: Only import ONE of these packages in your project. Choose based on your installed libvips version.

Check your libvips version with vips --version, then use the corresponding import:

// For libvips 8.18.x (latest - recommended)
import "github.com/cshum/vipsgen/vips"

// For libvips 8.17.x
import "github.com/cshum/vipsgen/vips817"

// For libvips 8.16.x
import "github.com/cshum/vipsgen/vips816"

func main() {
    // API is identical across all versions
    img, err := vips.NewImageFromFile("input.jpg", nil)
    if err != nil {
        log.Fatal(err)
    }
    defer img.Close()
    
    err = img.Resize(0.5, nil)
    // ...
}

Image Loaders

Generic loadersNewImageFromFile, NewImageFromBuffer, NewImageFromSource — automatically detect the image format and accept LoadOptions, a generic options struct covering common options across formats. Since not every format supports every option, use the format-specific loadersNewGifload, NewJpegloadBuffer, NewPngloadSource, etc. — for precise, type-safe control. A few common examples:

Animated GIFN: -1 loads all frames (full example):

image, err := vips.NewGifload("animation.gif", &vips.GifloadOptions{
    N: -1, // -1 = load all frames
})

JPEG auto-rotation — rotate by EXIF orientation on load:

source := vips.NewSource(reader)
defer source.Close()

image, err := vips.NewJpegloadSource(source, &vips.JpegloadSourceOptions{
    Autorotate: true,
})

Working with Animated Images

libvips represents multi-frame images (animated GIF, WebP) as a single vertically stacked image where each frame occupies one page of height PageHeight. vipsgen exposes the page metadata and provides dedicated helpers for operations that must process each frame individually.

Metadata

img.Pages()                 // number of frames
img.PageHeight()            // height of a single frame in pixels
delays, _ := img.PageDelay() // per-frame delay in milliseconds
img.Loop()                  // loop count (0 = infinite)

Multi-page Helpers

Some operations — rotate, crop, embed — cannot be expressed as a single libvips pipeline call across a stacked image. vipsgen ships hand-written C helpers that loop over frames internally, so there is no per-frame CGo overhead from Go:

// Rotate all frames
err = img.RotMultiPage(vips.AngleD90)

// Crop all frames to the same region
err = img.ExtractAreaMultiPage(left, top, width, height)

// Embed (pad/extend) all frames to a new canvas
err = img.EmbedMultiPage(left, top, newWidth, newHeight, &vips.EmbedMultiPageOptions{
    Extend:     vips.ExtendBackground,
    Background: []float64{0, 0, 0, 0},
})

These methods automatically fall through to the equivalent single-frame operation when the image has only one page.

Code Generation

Code generation requires libvips to be built with GObject introspection support.

go install github.com/cshum/vipsgen/cmd/vipsgen@latest

Generate the bindings:

vipsgen -out ./vips

Use your custom-generated code:

package main

import (
    "yourproject/vips"
)

Command Line Options

Usage of vipsgen:
  -debug
        Enable debug json output
  -extract
        Extract embedded templates to a directory
  -extract-dir string
        Directory to extract templates to (default "./templates")
  -include-test
        Include test files in generated output
  -out string
        Output directory (default "./vips")
  -templates string
        Template directory (uses embedded templates if not specified)

How Code Generation Works

The generation process involves multiple layers to provide a type-safe, idiomatic Go API:

  1. Introspection Analysis: vipsgen uses GObject introspection to analyze the libvips API, extracting operation metadata, argument types, and enum definitions.

  2. Multi-Layer Generation: To create type-safe, idiomatic Go APIs from libvips dynamic parameter system, vipsgen creates a layered approach that handles both required and optional parameters.

  3. Type-Safe Bindings: The generated code is fully type-safe with proper Go types, structs, and enums based on centralized introspection data.

┌─────────────────────────────────────────────────────────────┐
│                    Go Method Layer                          │
│  • Methods on *Image struct                                 │
│  • Go enums and structs                                     │  
│  • Options structs for optional parameters                  │
│  • Type conversions (Go <-> C)                              │
└─────────────────────────────────────────────────────────────┘
                               │
┌─────────────────────────────────────────────────────────────┐
│                   Go Binding Layer                          │
│  • vipsgenAbc() - required parameters only                  │
│  • vipsgen
View on GitHub
GitHub Stars230
CategoryDevelopment
Updated13h ago
Forks9

Languages

Go Template

Security Score

100/100

Audited on Apr 1, 2026

No findings