govips

repository·master·Indexed 23 days ago

https://github.com/davidbyttow/govips

A high-performance Go wrapper for the libvips image processing library. It enables the creation of fast, concurrent image processing services by exposing libvips operations as Go types, supporting features such as smart crop thumbnails, resizing, format conversion (WebP, PNG, JPEG), color modulation, and image compositing.

Tokens
2.1K
Snippets
10
Records
10
Agent score
32%

What's inside govips

  1. Initialize and shutdown govips

    master

    Every govips application must explicitly start and shutdown the library to manage the underlying libvips lifecycle. Use vips.Startup(nil) at the beginning of your application and defer vips.Shutdown() to ensure resources are cleaned up.

    package main
    
    import (
    	"fmt"
    	"os"
    
    	"github.com/davidbyttow/govips/v2/vips"
    )
    
    func main() {
    	vips.Startup(nil)
    	defer vips.Shutdown()
    
    	// ... example code goes here
    }
  2. Install govips

    master

    To install govips, you must first ensure the system requirements are met, then use go get to add the package to your project.

    Requirements

    • libvips: version 8.14 or higher
    • C compatible compiler: such as gcc 4.6+ or clang 3.0+
    • Go: version 1.23 or higher

    Platform Specific Setup

    MacOS

    Install vips and pkg-config using Homebrew:

    brew install vips pkg-config

    Note: On MacOS, you may need to set the following environment variable for the package to compile:

    export CGO_CFLAGS_ALLOW="-Xpreprocessor"

    Windows

    It is recommended to use govips via WSL and Ubuntu. Native Windows execution is supported but not officially recommended or regularly tested.

    go get -u github.com/davidbyttow/govips/v2/vips
  3. Use jemalloc to reduce memory fragmentation

    master

    If setting MALLOC_ARENA_MAX does not resolve memory fragmentation issues, you can replace the standard allocator with jemalloc.

    1. Install the libjemalloc-dev package on your system.
    2. Build your application using specific CGO_CFLAGS and CGO_LDFLAGS to link against jemalloc and disable built-in malloc functions.
    CGO_CFLAGS="-fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free" CGO_LDFLAGS="-ljemalloc" go build
  4. Manage memory fragmentation with MALLOC_ARENA_MAX

    master

    Because libvips uses GLib for memory management, heavily multi-threaded Go programs may experience memory fragmentation and constantly growing RSS usage. You can mitigate this by setting the MALLOC_ARENA_MAX environment variable to a lower value (e.g., 2) to reduce the number of malloc arenas GLib creates.

    MALLOC_ARENA_MAX=2 application
  5. Load from a byte buffer and strip metadata

    master

    When processing images from memory (e.g., from an HTTP request), use vips.NewImageFromBuffer. To protect privacy or reduce file size, you can call RemoveMetadata() to strip EXIF and other metadata, or set StripMetadata: true in your export parameters.

    inputBytes, err := os.ReadFile("photo.jpg")
    if err != nil {
    	log.Fatal(err)
    }
    
    image, err := vips.NewImageFromBuffer(inputBytes)
    if err != nil {
    	log.Fatal(err)
    }
    
    // Strip all EXIF/metadata for privacy
    if err := image.RemoveMetadata(); err != nil {
    	log.Fatal(err)
    }
    
    buf, _, err := image.ExportJpeg(&vips.JpegExportParams{
    	Quality:       80,
    	StripMetadata: true,
    })
    if err != nil {
    	log.Fatal(err)
    }
    os.WriteFile("clean.jpg", buf, 0644)
  6. Adjust brightness, saturation, and hue

    master

    The Modulate method allows you to adjust color properties using the LCH color space.

    • Brightness: Multiplier (1.0 is no change).
    • Saturation: Multiplier (1.0 is no change).
    • Hue: Angle shift in degrees.
    // Bump brightness by 20%, desaturate by 30%, shift hue by 45 degrees
    if err := image.Modulate(1.2, 0.7, 45); err != nil {
    	log.Fatal(err)
    }
    
    buf, _, err := image.ExportJpeg(&vips.JpegExportParams{Quality: 90})
    if err != nil {
    	log.Fatal(err)
    }
    os.WriteFile("adjusted.jpg", buf, 0644)
  7. Composite images (Watermarking)

    master

    You can overlay one image onto another using the Composite method. This uses Porter-Duff blending modes. For a standard watermark overlay, use vips.BlendModeOver and specify the x and y coordinates.

    base, err := vips.NewImageFromFile("photo.jpg")
    if err != nil {
    	log.Fatal(err)
    }
    
    overlay, err := vips.NewImageFromFile("watermark.png")
    if err != nil {
    	log.Fatal(err)
    }
    
    // Place the watermark at position (20, 20) using "over" blending
    if err := base.Composite(overlay, vips.BlendModeOver, 20, 20); err != nil {
    	log.Fatal(err)
    }
    
    buf, _, err := base.ExportJpeg(&vips.JpegExportParams{Quality: 90})
    if err != nil {
    	log.Fatal(err)
    }
    os.WriteFile("watermarked.jpg", buf, 0644)
  8. Create thumbnails with smart crop

    master

    The vips.NewThumbnailFromFile function is the most efficient way to generate thumbnails because it only decodes the pixels required for the target size. You can specify a crop strategy using vips.InterestingAttention or other interest constants to ensure the most important part of the image is preserved.

    // Load and shrink to fit within 200x200, cropping to the most interesting region
    image, err := vips.NewThumbnailFromFile("photo.jpg", 200, 200, vips.InterestingAttention)
    if err != nil {
    	log.Fatal(err)
    }
    
    buf, _, err := image.ExportJpeg(&vips.JpegExportParams{Quality: 80})
    if err != nil {
    	log.Fatal(err)
    }
    os.WriteFile("thumb.jpg", buf, 0644)
  9. Convert image formats

    master

    Once an image is loaded, you can export it to various formats like WebP, PNG, or JPEG by calling the corresponding Export methods with their respective parameter structs.

    // Export as WebP (lossy)
    webpBuf, _, err := image.ExportWebp(&vips.WebpExportParams{Quality: 75})
    if err != nil {
    	log.Fatal(err)
    }
    os.WriteFile("photo.webp", webpBuf, 0644)
    
    // Export as PNG
    pngBuf, _, err := image.ExportPng(&vips.PngExportParams{Compression: 6})
    if err != nil {
    	log.Fatal(err)
    }
    os.WriteFile("photo.png", pngBuf, 0644)
  10. Resize an image

    master

    Use the Resize method to scale an image. You can specify a scale factor (e.g., 0.5 for 50%) and a resampling kernel. vips.KernelLanczos3 is recommended for high-quality, sharp results.

    // Scale to 50%
    if err := image.Resize(0.5, vips.KernelLanczos3); err != nil {
    	log.Fatal(err)
    }
    
    buf, _, err := image.ExportJpeg(&vips.JpegExportParams{Quality: 85})
    if err != nil {
    	log.Fatal(err)
    }
    os.WriteFile("resized.jpg", buf, 0644)