This package wraps the core functionality of libvips image processing library by exposing all image operations on first-class types in Go.
Libvips is generally 4-8x faster than other graphics processors such as GraphicsMagick and ImageMagick. Check the benchmark: Speed and Memory Use
The intent for this is to enable developers to build extremely fast image processors in Go, which is suited well for concurrent requests.
govips
was created to provide a fast image processing library for Go by wrapping libvips
. However, it relies on manually maintained Go APIs that call high-level C functions not originally intended for direct binding. This has led to significant challenges:
- Maintenance Burden: Manually keeping up with the frequent and excellent innovations in
libvips
is unsustainable for our small team. - Stability Issues: The manual binding approach has resulted in difficult-to-debug issues, including segmentation violations and memory leaks.
- Incomplete API Coverage: We cannot offer the full, rich feature set that
libvips
provides.
A better solution now exists: vipsgen
.
vipsgen
is a tool that automatically generates comprehensive, type-safe Go bindings directly from the libvips
GObject-Introspection
data. This is the official and recommended way to create bindings for GObject
-based libraries.
Using bindings generated by vipsgen
solves all the problems above and is the right path forward for the Go community. We recommend it for all new and existing projects that need the full power and stability of libvips
.
- libvips 8.10+
- C compatible compiler such as gcc 4.6+ or clang 3.0+
- Go 1.16+
Use homebrew to install vips and pkg-config:
brew install vips pkg-config
The recommended approach on Windows is to use Govips via WSL and Ubuntu.
If you need to run Govips natively on Windows, it's not difficult but will require some effort. We don't have a recommended environment or setup at the moment. Windows is also not in our list of CI/CD targets so Govips is not regularly tested for compatibility. If you would be willing to setup and maintain a robust CI/CD Windows environment, please open a PR, we would be pleased to accept your contribution and support Windows as a platform.
go get -u github.com/davidbyttow/govips/v2/vips
On MacOS, govips may not compile without first setting an environment variable:
export CGO_CFLAGS_ALLOW="-Xpreprocessor"
package main
import (
"fmt"
"os"
"github.com/davidbyttow/govips/v2/vips"
)
func checkError(err error) {
if err != nil {
fmt.Println("error:", err)
os.Exit(1)
}
}
func main() {
vips.Startup(nil)
defer vips.Shutdown()
image1, err := vips.NewImageFromFile("input.jpg")
checkError(err)
// Rotate the picture upright and reset EXIF orientation tag
err = image1.AutoRotate()
checkError(err)
ep := vips.NewDefaultJPEGExportParams()
image1bytes, _, err := image1.Export(ep)
err = os.WriteFile("output.jpg", image1bytes, 0644)
checkError(err)
}
See examples/ folder for more examples.
$ make test
libvips
uses GLib for memory management, and it brings GLib memory fragmentation
issues to heavily multi-threaded programs. First thing you can try if you noticed
constantly growing RSS usage without Go's sys memory growth is set MALLOC_ARENA_MAX
:
MALLOC_ARENA_MAX=2 application
This will reduce GLib memory appetites by reducing the number of malloc arenas that it can create. By default GLib creates one are per thread, and this would follow to memory fragmentation.
If the arena option doesn't help, you can try replacing the standard allocator with jemalloc
,
which emphasizes fragmentation avoidance and scalable concurrency support.
To do this, you need to install the libjemalloc-dev
package.
And pass the following flags for build command:
CGO_CFLAGS="-fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free" CGO_LDFLAGS="-ljemalloc" go build
Feel free to file issues or create pull requests. See this guide on contributing for more information.
Thanks to:
- John Cupitt for creating and maintaining libvips
- Toni Melisma for pushing to a 2.x release
- wix.com for the govips logo and lots of great functionality
- All of our fantastic contributors
MIT