CLI tool
anthonynsimon/bild avatar
anthonynsimon/bild

bild: image processing in pure Go, with a CLI riding on top

Image processing algorithms in pure Go

4,216 stars219 forksGoMIT

At a glance

What is it?
bild is a MIT-licensed collection of parallel image processing algorithms in pure Go, aiming at simplicity of use and development over absolute performance, built on the standard library's image types with WebP added, exposed as both an importable package and a cobra-driven command line covering adjust, blend, blur, channel, effect, histogram, noise, segment and transform operations. It requires Go 1.25 or newer and released v0.17.1 in September 2026.
Who is it for?
Use bild when Go code needs common image operations, color adjustment, convolution effects, resizing with quality filters, format conversion, without cgo or a graphics stack, and when the standard library's image types are the natural currency of the codebase. Reach for a C-backed library when absolute throughput is the requirement, since the project itself ranks simplicity above performance.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 24 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 1, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Standard library in, standard library out

bild states three commitments in its opening lines, a collection of parallel image processing algorithms in pure Go, simplicity in use and development over absolute high performance, and packages from the standard library whenever possible to reduce dependency use. The fourth sentence carries the API contract, all operations return image types from the standard library, so results flow into any other Go code expecting image.Image without conversion layers. The purity is visible in the dependency list, exactly three requires, nativewebp for WebP support, cobra for the command line, and golang.org/x/image, everything else being the standard library and the project's own packages. Most algorithms are designed to be efficient and make use of parallelism when available, a parallel directory in the repository holding that machinery, and the honest ordering of the goals, simplicity first, performance second, tells you what to expect when reading the code.

A CLI that mirrors the packages

The command line surface maps one-to-one onto the library's packages, adjust, blend, blur, channel, effect, histogram, imgio, noise, segment and transform, each subcommand exposing the operations its package provides. The documented examples read like the operations a non-programmer would want:

code
bild effect median --radius 1.5 input.png output.png
code
bild transform resize --width 800 --height 600 --filter lanczos input.png output.png

Rotation with expanded bounds, cropping by rectangle, and format conversion follow the same shape, transform rotate --angle 90 --resize-bounds, transform crop --rect 0x0+512x256, and imgio encode input.png output.webp, with the encoder chosen from the output file extension, .png, .jpg and .jpeg, .bmp, or .webp. Binaries are pre-compiled on the releases page for platforms the Makefile targets, Linux and Darwin on amd64 and arm64 as tarballs, or the tool compiles from source with go get. The CLI makes the library useful to scripts and pipelines that never import a package.

The package API in one main function

The package usage example is the entire mental model, open, chain operations, save:

go
package main

import (
    "github.com/anthonynsimon/bild/effect"
    "github.com/anthonynsimon/bild/imgio"
    "github.com/anthonynsimon/bild/transform"
)

func main() {
    img, err := imgio.Open("input.jpg")
    if err != nil {
        fmt.Println(err)
        return
    }

    inverted := effect.Invert(img)
    resized := transform.Resize(inverted, 800, 800, transform.Linear)
    rotated := transform.Rotate(resized, 45, nil)

    if err := imgio.Save("output.png", rotated, imgio.PNGEncoder()); err != nil {
        fmt.Println(err)
        return
    }
}

Each operation takes an image and returns an image, the composition is plain function calls, and imgio.Open decodes PNG, JPEG, BMP and WebP while Save takes an explicit encoder, PNGEncoder(), JPEGEncoder(quality), BMPEncoder() or WEBPEncoder(options) with nil for defaults. There is no context object, no builder, no session to manage, the kind of API where the example is also the reference.

Adjust, blend and channel: the color operations

The adjust package covers the basic photographic controls, each a one-liner, adjust.Brightness(img, 0.25), adjust.Contrast(img, -0.5), adjust.Gamma(img, 2.2), adjust.Hue(img, -42) and adjust.Saturation(img, 0.5), the sign conventions and scales documented through the examples themselves. The blend package implements sixteen layer blend modes, Add through Soft Light and Subtract, the Photoshop vocabulary, invoked as blend.Multiply(bg, fg) and its siblings, the kind of operations compositing pipelines need between two images rather than on one. The channel package extracts what its name says, channel.Extract(img, channel.Alpha) for one channel and channel.ExtractMultiple(img, channel.Red, channel.Alpha) for several at once, useful for splitting an image into the planes another stage processes separately. Together the three packages cover the color algebra most scripts need before geometry enters.

Convolution effects and noise generation

The effect package is the largest, and its function list doubles as an image editing menu, Dilate, Erode, EdgeDetection, Emboss, Grayscale, Invert, Median, Sepia, Sharpen, Sobel and UnsharpMask, each taking an image plus the parameters the operation needs, effect.Median(img, 10.0), effect.EdgeDetection(img, 1.0), effect.UnsharpMask(img, 0.6, 1.2), a convolution directory in the repository holding the shared machinery. The blur package contributes Box and Gaussian, blur.Box(img, 3.0) and blur.Gaussian(img, 3.0), the two ends of the speed-quality trade. The noise package runs the other direction, generating images rather than transforming them, noise.Generate with an Options struct selecting monochrome or color and a noise function, Uniform, Binary or Gaussian, plus noise.GeneratePerlin(280, 280, 0.25) for Perlin noise, the texture-generation staple. A perlin directory in the tree marks that implementation as its own module of the library.

Transforms with six resampling filters

The transform package carries the geometry, Crop by rectangle, FlipH and FlipV, Resize, and Rotate with options. Resize is where the quality lives, offering six resampling filters, Nearest Neighbor, Linear, Gaussian, Mitchell Netravali, Catmull Rom and Lanczos, selected as a constant in the call, transform.Resize(img, 280, 280, transform.Linear), and mirrored on the CLI by --filter lanczos, the surfaces staying parallel. Rotate takes an options struct or nil for defaults, pivot at center and ResizeBounds false, with ResizeBounds true using the full rotation bounding area so nothing is clipped, the exact option the CLI exposes as --resize-bounds. The paint package adds FloodFill with a fuzz parameter, the percentage of maximum color distance tolerated, paint.FloodFill(img, image.Point{240, 0}, color.RGBA{255, 0, 0, 255}, 15), and segment.Threshold(img, 128) rounds out the analysis side with binary segmentation.

A quietly maintained one-dependency-three toolchain

The engineering around the library is conventional Go discipline. The Makefile runs tests with a timeout, a race mode, a coverage mode producing an HTML report, and a bench mode with -benchmem over five-second benchmarks, with a benchmarks.txt file in the repository recording results. The release path cross-compiles four binaries, Linux and Darwin on amd64 and arm64, each tarred into dist, static for Linux. A CLAUDE.md sits in the tree for coding assistants, and the changelog records the line, v0.16.1 in July 2026, v0.17.0 in August and v0.17.1 on 2026-09-07, the same day as the last push. Against the wider Go imaging ecosystem, the pitch remains what its opening lines promised, no cgo, no native dependencies, standard types throughout, and a function-per-operation API that trades peak throughput for code a reader can hold in mind, the trade a large class of projects should take happily.

Editorial conclusion

Use bild when Go code needs common image operations, color adjustment, convolution effects, resizing with quality filters, format conversion, without cgo or a graphics stack, and when the standard library's image types are the natural currency of the codebase. Reach for a C-backed library when absolute throughput is the requirement, since the project itself ranks simplicity above performance. Verify first that your format needs are within PNG, JPEG, BMP and WebP, pin Go 1.25 or newer for the package, and try the CLI on a sample image to see whether the packaged operations cover the workflow before writing Go against it.

Frequently asked questions

What is bild, the Go library?

bild is a MIT-licensed collection of parallel image processing algorithms in pure Go, prioritizing simplicity of use and development over absolute performance. All operations accept and return standard library image types, and it ships both an importable package and a command line tool.

Which image formats does bild support?

imgio.Open decodes PNG, JPEG, BMP and WebP images. Saving uses explicit encoders, imgio.PNGEncoder(), imgio.JPEGEncoder(quality), imgio.BMPEncoder() and imgio.WEBEncoder(options) with nil for defaults, and the CLI selects the encoder from the output file extension.

What resampling filters does bild's resize offer?

Six filters: Nearest Neighbor, Linear, Gaussian, Mitchell Netravali, Catmull Rom and Lanczos, chosen as a constant in transform.Resize or through the --filter flag on the CLI resize command.

Official sources

  1. anthonynsimon/bild on GitHub
  2. Issues
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/anthonynsimon-bild.svg)](https://hysenlabs.com/projects/anthonynsimon-bild)