The Go image package
21 Sep 2011
Tags: image, libraries, technical

Nigel Tao

* Introduction

The [[https://golang.org/pkg/image/][image]] and [[https://golang.org/pkg/image/color/][image/color]] packages define a number of types: `color.Color` and `color.Model` describe colors, `image.Point` and `image.Rectangle` describe basic 2-D geometry, and `image.Image` brings the two concepts together to represent a rectangular grid of colors. A [[https://golang.org/doc/articles/image_draw.html][separate article]] covers image composition with the [[https://golang.org/pkg/image/draw/][image/draw]] package.

* Colors and Color Models

[[https://golang.org/pkg/image/color/#Color][Color]] is an interface that defines the minimal method set of any type that can be considered a color: one that can be converted to red, green, blue and alpha values. The conversion may be lossy, such as converting from CMYK or YCbCr color spaces.

	type Color interface {
	    // RGBA returns the alpha-premultiplied red, green, blue and alpha values
	    // for the color. Each value ranges within [0, 0xFFFF], but is represented
	    // by a uint32 so that multiplying by a blend factor up to 0xFFFF will not
	    // overflow.
	    RGBA() (r, g, b, a uint32)
	}

There are three important subtleties about the return values. First, the red, green and blue are alpha-premultiplied: a fully saturated red that is also 25% transparent is represented by RGBA returning a 75% r. Second, the channels have a 16-bit effective range: 100% red is represented by RGBA returning an r of 65535, not 255, so that converting from CMYK or YCbCr is not as lossy. Third, the type returned is `uint32`, even though the maximum value is 65535, to guarantee that multiplying two values together won't overflow. Such multiplications occur when blending two colors according to an alpha mask from a third color, in the style of [[https://en.wikipedia.org/wiki/Alpha_compositing][Porter and Duff's]] classic algebra:

	dstr, dstg, dstb, dsta := dst.RGBA()
	srcr, srcg, srcb, srca := src.RGBA()
	_, _, _, m := mask.RGBA()
	const M = 1<<16 - 1
	// The resultant red value is a blend of dstr and srcr, and ranges in [0, M].
	// The calculation for green, blue and alpha is similar.
	dstr = (dstr*(M-m) + srcr*m) / M

The last line of that code snippet would have been more complicated if we worked with non-alpha-premultiplied colors, which is why `Color` uses alpha-premultiplied values.

The image/color package also defines a number of concrete types that implement the `Color` interface. For example, [[https://golang.org/pkg/image/color/#RGBA][`RGBA`]] is a struct that represents the classic "8 bits per channel" color.

	type RGBA struct {
	    R, G, B, A uint8
	}

Note that the `R` field of an `RGBA` is an 8-bit alpha-premultiplied color in the range [0, 255]. `RGBA` satisfies the `Color` interface by multiplying that value by 0x101 to generate a 16-bit alpha-premultiplied color in the range [0, 65535]. Similarly, the [[https://golang.org/pkg/image/color/#NRGBA][`NRGBA`]] struct type represents an 8-bit non-alpha-premultiplied color, as used by the PNG image format. When manipulating an `NRGBA`'s fields directly, the values are non-alpha-premultiplied, but when calling the `RGBA` method, the return values are alpha-premultiplied.

A [[https://golang.org/pkg/image/color/#Model][`Model`]] is simply something that can convert `Color`s to other `Color`s, possibly lossily. For example, the `GrayModel` can convert any `Color` to a desaturated [[https://golang.org/pkg/image/color/#Gray][`Gray`]]. A `Palette` can convert any `Color` to one from a limited palette.

	type Model interface {
	    Convert(c Color) Color
	}

	type Palette []Color

* Points and Rectangles

A [[https://golang.org/pkg/image/#Point][`Point`]] is an (x, y) co-ordinate on the integer grid, with axes increasing right and down. It is neither a pixel nor a grid square. A `Point` has no intrinsic width, height or color, but the visualizations below use a small colored square.

	type Point struct {
	    X, Y int
	}

.image go-image-package_image-package-01.png

	    p := image.Point{2, 1}

A [[https://golang.org/pkg/image/#Rectangle][`Rectangle`]] is an axis-aligned rectangle on the integer grid, defined by its top-left and bottom-right `Point`.  A `Rectangle` also has no intrinsic color, but the visualizations below outline rectangles with a thin colored line, and call out their `Min` and `Max` `Point`s.

	type Rectangle struct {
	    Min, Max Point
	}

For convenience, `image.Rect(x0,`y0,`x1,`y1)` is equivalent to `image.Rectangle{image.Point{x0,`y0},`image.Point{x1,`y1}}`, but is much easier to type.

A `Rectangle` is inclusive at the top-left and exclusive at the bottom-right. For a `Point`p` and a `Rectangle`r`, `p.In(r)` if and only if `r.Min.X`<=`p.X`&&`p.X`<`r.Max.X`, and similarly for `Y`. This is analogous to how a slice `s[i0:i1]` is inclusive at the low end and exclusive at the high end. (Unlike arrays and slices, a `Rectangle` often has a non-zero origin.)

.image go-image-package_image-package-02.png

	    r := image.Rect(2, 1, 5, 5)
	    // Dx and Dy return a rectangle's width and height.
	    fmt.Println(r.Dx(), r.Dy(), image.Pt(0, 0).In(r)) // prints 3 4 false

Adding a `Point` to a `Rectangle` translates the `Rectangle`. Points and Rectangles are not restricted to be in the bottom-right quadrant.

.image go-image-package_image-package-03.png

	    r := image.Rect(2, 1, 5, 5).Add(image.Pt(-4, -2))
	    fmt.Println(r.Dx(), r.Dy(), image.Pt(0, 0).In(r)) // prints 3 4 true

Intersecting two Rectangles yields another Rectangle, which may be empty.

.image go-image-package_image-package-04.png

	    r := image.Rect(0, 0, 4, 3).Intersect(image.Rect(2, 2, 5, 5))
	    // Size returns a rectangle's width and height, as a Point.
	    fmt.Printf("%#v\n", r.Size()) // prints image.Point{X:2, Y:1}

Points and Rectangles are passed and returned by value. A function that takes a `Rectangle` argument will be as efficient as a function that takes two `Point` arguments, or four `int` arguments.

* Images

An [[https://golang.org/pkg/image/#Image][Image]] maps every grid square in a `Rectangle` to a `Color` from a `Model`. "The pixel at (x, y)" refers to the color of the grid square defined by the points (x, y), (x+1, y), (x+1, y+1) and (x, y+1).

	type Image interface {
	    // ColorModel returns the Image's color model.
	    ColorModel() color.Model
	    // Bounds returns the domain for which At can return non-zero color.
	    // The bounds do not necessarily contain the point (0, 0).
	    Bounds() Rectangle
	    // At returns the color of the pixel at (x, y).
	    // At(Bounds().Min.X, Bounds().Min.Y) returns the upper-left pixel of the grid.
	    // At(Bounds().Max.X-1, Bounds().Max.Y-1) returns the lower-right one.
	    At(x, y int) color.Color
	}

A common mistake is assuming that an `Image`'s bounds start at (0, 0). For example, an animated GIF contains a sequence of Images, and each `Image` after the first typically only holds pixel data for the area that changed, and that area doesn't necessarily start at (0, 0). The correct way to iterate over an `Image` m's pixels looks like:

	b := m.Bounds()
	for y := b.Min.Y; y < b.Max.Y; y++ {
	 for x := b.Min.X; x < b.Max.X; x++ {
	  doStuffWith(m.At(x, y))
	 }
	}

`Image` implementations do not have to be based on an in-memory slice of pixel data. For example, a [[https://golang.org/pkg/image/#Uniform][`Uniform`]] is an `Image` of enormous bounds and uniform color, whose in-memory representation is simply that color.

	type Uniform struct {
	    C color.Color
	}

Typically, though, programs will want an image based on a slice. Struct types like [[https://golang.org/pkg/image/#RGBA][`RGBA`]] and [[https://golang.org/pkg/image/#Gray][`Gray`]] (which other packages refer to as `image.RGBA` and `image.Gray`) hold slices of pixel data and implement the `Image` interface.

	type RGBA struct {
	    // Pix holds the image's pixels, in R, G, B, A order. The pixel at
	    // (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*4].
	    Pix []uint8
	    // Stride is the Pix stride (in bytes) between vertically adjacent pixels.
	    Stride int
	    // Rect is the image's bounds.
	    Rect Rectangle
	}

These types also provide a `Set(x,`y`int,`c`color.Color)` method that allows modifying the image one pixel at a time.

	    m := image.NewRGBA(image.Rect(0, 0, 640, 480))
	    m.Set(5, 5, color.RGBA{255, 0, 0, 255})

If you're reading or writing a lot of pixel data, it can be more efficient, but more complicated, to access these struct type's `Pix` field directly.

The slice-based `Image` implementations also provide a `SubImage` method, which returns an `Image` backed by the same array. Modifying the pixels of a sub-image will affect the pixels of the original image, analogous to how modifying the contents of a sub-slice `s[i0:i1]` will affect the contents of the original slice `s`.

.image go-image-package_image-package-05.png

	    m0 := image.NewRGBA(image.Rect(0, 0, 8, 5))
	    m1 := m0.SubImage(image.Rect(1, 2, 5, 5)).(*image.RGBA)
	    fmt.Println(m0.Bounds().Dx(), m1.Bounds().Dx()) // prints 8, 4
	    fmt.Println(m0.Stride == m1.Stride)             // prints true

For low-level code that works on an image's `Pix` field, be aware that ranging over `Pix` can affect pixels outside an image's bounds. In the example above, the pixels covered by `m1.Pix` are shaded in blue. Higher-level code, such as the `At` and `Set` methods or the [[https://golang.org/pkg/image/draw/][image/draw package]], will clip their operations to the image's bounds.

* Image Formats

The standard package library supports a number of common image formats, such as GIF, JPEG and PNG. If you know the format of a source image file, you can decode from an [[https://golang.org/pkg/io/#Reader][`io.Reader`]] directly.

	import (
	 "image/jpeg"
	 "image/png"
	 "io"
	)

	// convertJPEGToPNG converts from JPEG to PNG.
	func convertJPEGToPNG(w io.Writer, r io.Reader) error {
	 img, err := jpeg.Decode(r)
	 if err != nil {
	  return err
	 }
	 return png.Encode(w, img)
	}

If you have image data of unknown format, the [[https://golang.org/pkg/image/#Decode][`image.Decode`]] function can detect the format. The set of recognized formats is constructed at run time and is not limited to those in the standard package library. An image format package typically registers its format in an init function, and the main package will "underscore import" such a package solely for the side effect of format registration.

	import (
	 "image"
	 "image/png"
	 "io"

	 _ "code.google.com/p/vp8-go/webp"
	 _ "image/jpeg"
	)

	// convertToPNG converts from any recognized format to PNG.
	func convertToPNG(w io.Writer, r io.Reader) error {
	 img, _, err := image.Decode(r)
	 if err != nil {
	  return err
	 }
	 return png.Encode(w, img)
	}
