image: Index | Examples | Files

package draw

import ""

Package draw provides image composition functions.

See "The Go image/draw package" for an introduction to this package:

This package is a superset of and a drop-in replacement for the image/draw package in the standard library.



Package Files

draw.go impl.go scale.go


var (
    // NearestNeighbor is the nearest neighbor interpolator. It is very fast,
    // but usually gives very low quality results. When scaling up, the result
    // will look 'blocky'.
    NearestNeighbor = Interpolator(nnInterpolator{})

    // ApproxBiLinear is a mixture of the nearest neighbor and bi-linear
    // interpolators. It is fast, but usually gives medium quality results.
    // It implements bi-linear interpolation when upscaling and a bi-linear
    // blend of the 4 nearest neighbor pixels when downscaling. This yields
    // nicer quality than nearest neighbor interpolation when upscaling, but
    // the time taken is independent of the number of source pixels, unlike the
    // bi-linear interpolator. When downscaling a large image, the performance
    // difference can be significant.
    ApproxBiLinear = Interpolator(ablInterpolator{})

    // BiLinear is the tent kernel. It is slow, but usually gives high quality
    // results.
    BiLinear = &Kernel{1, func(t float64) float64 {
        return 1 - t

    // CatmullRom is the Catmull-Rom kernel. It is very slow, but usually gives
    // very high quality results.
    // It is an instance of the more general cubic BC-spline kernel with parameters
    // B=0 and C=0.5. See Mitchell and Netravali, "Reconstruction Filters in
    // Computer Graphics", Computer Graphics, Vol. 22, No. 4, pp. 221-228.
    CatmullRom = &Kernel{2, func(t float64) float64 {
        if t < 1 {
            return (1.5*t-2.5)*t*t + 1
        return ((-0.5*t+2.5)*t-4)*t + 2

func Copy Uses

func Copy(dst Image, dp image.Point, src image.Image, sr image.Rectangle, op Op, opts *Options)

Copy copies the part of the source image defined by src and sr and writes the result of a Porter-Duff composition to the part of the destination image defined by dst and the translation of sr so that sr.Min translates to dp.

func Draw Uses

func Draw(dst Image, r image.Rectangle, src image.Image, sp image.Point, op Op)

Draw calls DrawMask with a nil mask.


fSrc, err := os.Open("../testdata/blue-purple-pink.png")
if err != nil {
defer fSrc.Close()
src, err := png.Decode(fSrc)
if err != nil {

dst := image.NewRGBA(image.Rect(0, 0, 400, 300))
green := image.NewUniform(color.RGBA{0x00, 0x1f, 0x00, 0xff})
draw.Copy(dst, image.Point{}, green, dst.Bounds(), draw.Src, nil)
qs := []draw.Interpolator{
const cos60, sin60 = 0.5, 0.866025404
t := f64.Aff3{
    +2 * cos60, -2 * sin60, 100,
    +2 * sin60, +2 * cos60, 100,

draw.Copy(dst, image.Point{20, 30}, src, src.Bounds(), draw.Over, nil)
for i, q := range qs {
    q.Scale(dst, image.Rect(200+10*i, 100*i, 600+10*i, 150+100*i), src, src.Bounds(), draw.Over, nil)
draw.NearestNeighbor.Transform(dst, t, src, src.Bounds(), draw.Over, nil)

red := image.NewNRGBA(image.Rect(0, 0, 16, 16))
for y := 0; y < 16; y++ {
    for x := 0; x < 16; x++ {
        red.SetNRGBA(x, y, color.NRGBA{
            R:  uint8(x * 0x11),
            A:  uint8(y * 0x11),
red.SetNRGBA(0, 0, color.NRGBA{0xff, 0xff, 0x00, 0xff})
red.SetNRGBA(15, 15, color.NRGBA{0xff, 0xff, 0x00, 0xff})

ops := []draw.Op{
for i, op := range ops {
    dr := image.Rect(120+10*i, 150+60*i, 170+10*i, 200+60*i)
    draw.NearestNeighbor.Scale(dst, dr, red, red.Bounds(), op, nil)
    t := f64.Aff3{
        +cos60, -sin60, float64(190 + 10*i),
        +sin60, +cos60, float64(140 + 50*i),
    draw.NearestNeighbor.Transform(dst, t, red, red.Bounds(), op, nil)

dr := image.Rect(0, 0, 128, 128)
checkerboard := image.NewAlpha(dr)
for y := dr.Min.Y; y < dr.Max.Y; y++ {
    for x := dr.Min.X; x < dr.Max.X; x++ {
        if (x/20)%2 == (y/20)%2 {
            checkerboard.SetAlpha(x, y, color.Alpha{0xff})
sr := image.Rect(0, 0, 16, 16)
circle := image.NewAlpha(sr)
for y := sr.Min.Y; y < sr.Max.Y; y++ {
    for x := sr.Min.X; x < sr.Max.X; x++ {
        dx, dy := x-10, y-8
        if d := 32 * math.Sqrt(float64(dx*dx)+float64(dy*dy)); d < 0xff {
            circle.SetAlpha(x, y, color.Alpha{0xff - uint8(d)})
cyan := image.NewUniform(color.RGBA{0x00, 0xff, 0xff, 0xff})
draw.NearestNeighbor.Scale(dst, dr, cyan, sr, draw.Over, &draw.Options{
    DstMask: checkerboard,
    SrcMask: circle,

// Change false to true to write the resultant image to disk.
if false {
    fDst, err := os.Create("out.png")
    if err != nil {
    defer fDst.Close()
    err = png.Encode(fDst, dst)
    if err != nil {

fmt.Printf("dst has bounds %v.\n", dst.Bounds())


dst has bounds (0,0)-(400,300).

func DrawMask Uses

func DrawMask(dst Image, r image.Rectangle, src image.Image, sp image.Point, mask image.Image, mp image.Point, op Op)

DrawMask aligns r.Min in dst with sp in src and mp in mask and then replaces the rectangle r in dst with the result of a Porter-Duff composition. A nil mask is treated as opaque.

type Drawer Uses

type Drawer = draw.Drawer

Drawer contains the Draw method.

var FloydSteinberg Drawer = floydSteinberg{}

FloydSteinberg is a Drawer that is the Src Op with Floyd-Steinberg error diffusion.

type Image Uses

type Image = draw.Image

Image is an image.Image with a Set method to change a single pixel.

type Interpolator Uses

type Interpolator interface {

Interpolator is an interpolation algorithm, when dst and src pixels don't have a 1:1 correspondence.

Of the interpolators provided by this package:

- NearestNeighbor is fast but usually looks worst.
- CatmullRom is slow but usually looks best.
- ApproxBiLinear has reasonable speed and quality.

The time taken depends on the size of dr. For kernel interpolators, the speed also depends on the size of sr, and so are often slower than non-kernel interpolators, especially when scaling down.

type Kernel Uses

type Kernel struct {
    // Support is the kernel support and must be >= 0. At(t) is assumed to be
    // zero when t >= Support.
    Support float64
    // At is the kernel function. It will only be called with t in the
    // range [0, Support).
    At  func(t float64) float64

Kernel is an interpolator that blends source pixels weighted by a symmetric kernel function.

func (*Kernel) NewScaler Uses

func (q *Kernel) NewScaler(dw, dh, sw, sh int) Scaler

NewScaler returns a Scaler that is optimized for scaling multiple times with the same fixed destination and source width and height.

func (*Kernel) Scale Uses

func (q *Kernel) Scale(dst Image, dr image.Rectangle, src image.Image, sr image.Rectangle, op Op, opts *Options)

Scale implements the Scaler interface.

func (*Kernel) Transform Uses

func (q *Kernel) Transform(dst Image, s2d f64.Aff3, src image.Image, sr image.Rectangle, op Op, opts *Options)

type Op Uses

type Op = draw.Op

Op is a Porter-Duff compositing operator.

const (
    // Over specifies ``(src in mask) over dst''.
    Over Op  = draw.Over
    // Src specifies ``src in mask''.
    Src Op  = draw.Src

type Options Uses

type Options struct {
    // Masks limit what parts of the dst image are drawn to and what parts of
    // the src image are drawn from.
    // A dst or src mask image having a zero alpha (transparent) pixel value in
    // the respective coordinate space means that dst pixel is entirely
    // unaffected or that src pixel is considered transparent black. A full
    // alpha (opaque) value means that the dst pixel is maximally affected or
    // the src pixel contributes maximally. The default values, nil, are
    // equivalent to fully opaque, infinitely large mask images.
    // The DstMask is otherwise known as a clip mask, and its pixels map 1:1 to
    // the dst image's pixels. DstMaskP in DstMask space corresponds to
    // image.Point{X:0, Y:0} in dst space. For example, when limiting
    // repainting to a 'dirty rectangle', use that image.Rectangle and a zero
    // image.Point as the DstMask and DstMaskP.
    // The SrcMask's pixels map 1:1 to the src image's pixels. SrcMaskP in
    // SrcMask space corresponds to image.Point{X:0, Y:0} in src space. For
    // example, when drawing font glyphs in a uniform color, use an
    // *image.Uniform as the src, and use the glyph atlas image and the
    // per-glyph offset as SrcMask and SrcMaskP:
    //	Copy(dst, dp, image.NewUniform(color), image.Rect(0, 0, glyphWidth, glyphHeight), &Options{
    //		SrcMask:  glyphAtlas,
    //		SrcMaskP: glyphOffset,
    //	})
    DstMask  image.Image
    DstMaskP image.Point
    SrcMask  image.Image
    SrcMaskP image.Point

Options are optional parameters to Copy, Scale and Transform.

A nil *Options means to use the default (zero) values of each field.

type Quantizer Uses

type Quantizer = draw.Quantizer

Quantizer produces a palette for an image.

type Scaler Uses

type Scaler interface {
    Scale(dst Image, dr image.Rectangle, src image.Image, sr image.Rectangle, op Op, opts *Options)

Scaler scales the part of the source image defined by src and sr and writes the result of a Porter-Duff composition to the part of the destination image defined by dst and dr.

A Scaler is safe to use concurrently.

type Transformer Uses

type Transformer interface {
    Transform(dst Image, m f64.Aff3, src image.Image, sr image.Rectangle, op Op, opts *Options)

Transformer transforms the part of the source image defined by src and sr and writes the result of a Porter-Duff composition to the part of the destination image defined by dst and the affine transform m applied to sr.

For example, if m is the matrix

m00 m01 m02
m10 m11 m12

then the src-space point (sx, sy) maps to the dst-space point (m00*sx + m01*sy + m02, m10*sx + m11*sy + m12).

A Transformer is safe to use concurrently.

Package draw imports 6 packages (graph) and is imported by 161 packages. Updated 2020-12-09. Refresh now. Tools for package owners.