github.com/varialus/godfly@v0.0.0-20130904042352-1934f9f095ab/doc/articles/image_draw.html (about) 1 <!--{ 2 "Title": "The Go image/draw package", 3 "Template": true 4 }--> 5 6 <p> 7 <a href="/pkg/image/draw/">Package image/draw</a> defines 8 only one operation: drawing a source image onto a destination 9 image, through an optional mask image. This one operation is 10 surprisingly versatile and can perform a number of common image 11 manipulation tasks elegantly and efficiently. 12 </p> 13 14 <p> 15 Composition is performed pixel by pixel in the style of the Plan 9 16 graphics library and the X Render extension. The model is based on 17 the classic "Compositing Digital Images" paper by Porter and Duff, 18 with an additional mask parameter: <code>dst = (src IN mask) OP dst</code>. 19 For a fully opaque mask, this reduces to the original Porter-Duff 20 formula: <code>dst = src OP dst</code>. In Go, a nil mask image is equivalent 21 to an infinitely sized, fully opaque mask image. 22 </p> 23 24 <p> 25 The Porter-Duff paper presented 26 <a href="http://www.w3.org/TR/SVGCompositing/examples/compop-porterduff-examples.png">12 different composition operators</a>, 27 but with an explicit mask, only 2 of these are needed in practice: 28 source-over-destination and source. In Go, these operators are 29 represented by the <code>Over</code> and <code>Src</code> constants. The <code>Over</code> operator 30 performs the natural layering of a source image over a destination 31 image: the change to the destination image is smaller where the 32 source (after masking) is more transparent (that is, has lower 33 alpha). The <code>Src</code> operator merely copies the source (after masking) 34 with no regard for the destination image's original content. For 35 fully opaque source and mask images, the two operators produce the 36 same output, but the <code>Src</code> operator is usually faster. 37 </p> 38 39 <p><b>Geometric Alignment</b></p> 40 41 <p> 42 Composition requires associating destination pixels with source and 43 mask pixels. Obviously, this requires destination, source and mask 44 images, and a composition operator, but it also requires specifying 45 what rectangle of each image to use. Not every drawing should write 46 to the entire destination: when updating an animating image, it is 47 more efficient to only draw the parts of the image that have 48 changed. Not every drawing should read from the entire source: when 49 using a sprite that combines many small images into one large one, 50 only a part of the image is needed. Not every drawing should read 51 from the entire mask: a mask image that collects a font's glyphs is 52 similar to a sprite. Thus, drawing also needs to know three 53 rectangles, one for each image. Since each rectangle has the same 54 width and height, it suffices to pass a destination rectangle `r` 55 and two points <code>sp</code> and <code>mp</code>: the source rectangle is equal to <code>r</code> 56 translated so that <code>r.Min</code> in the destination image aligns with 57 <code>sp</code> in the source image, and similarly for <code>mp</code>. The effective 58 rectangle is also clipped to each image's bounds in their 59 respective co-ordinate space. 60 </p> 61 62 <p> 63 <img src="image-20.png"> 64 </p> 65 66 <p> 67 The <a href="/pkg/image/draw/#DrawMask"><code>DrawMask</code></a> 68 function takes seven arguments, but an explicit mask and mask-point 69 are usually unnecessary, so the 70 <a href="/pkg/image/draw/#Draw"><code>Draw</code></a> function takes five: 71 </p> 72 73 <pre> 74 // Draw calls DrawMask with a nil mask. 75 func Draw(dst Image, r image.Rectangle, src image.Image, sp image.Point, op Op) 76 func DrawMask(dst Image, r image.Rectangle, src image.Image, sp image.Point, 77 mask image.Image, mp image.Point, op Op) 78 </pre> 79 80 <p> 81 The destination image must be mutable, so the image/draw package 82 defines a <a href="/pkg/image/draw/#Image"><code>draw.Image</code></a> 83 interface which has a <code>Set</code> method. 84 </p> 85 86 {{code "../src/pkg/image/draw/draw.go" `/type Image/` `/}/`}} 87 88 <p><b>Filling a Rectangle</b></p> 89 90 <p> 91 To fill a rectangle with a solid color, use an <code>image.Uniform</code> 92 source. The <code>Uniform</code> type re-interprets a <code>Color</code> as a 93 practically infinite-sized <code>Image</code> of that color. For those 94 familiar with the design of Plan 9's draw library, there is no need 95 for an explicit "repeat bit" in Go's slice-based image types; the 96 concept is subsumed by <code>Uniform</code>. 97 </p> 98 99 {{code "/doc/progs/image_draw.go" `/ZERO/` `/STOP/`}} 100 101 <p> 102 To initialize a new image to all-blue: 103 </p> 104 105 {{code "/doc/progs/image_draw.go" `/BLUE/` `/STOP/`}} 106 107 <p> 108 To reset an image to transparent (or black, if the destination 109 image's color model cannot represent transparency), use 110 <code>image.Transparent</code>, which is an <code>image.Uniform</code>: 111 </p> 112 113 {{code "/doc/progs/image_draw.go" `/RESET/` `/STOP/`}} 114 115 <p> 116 <img src="image-2a.png"> 117 </p> 118 119 120 <p><b>Copying an Image</b></p> 121 122 <p> 123 To copy from a rectangle <code>sr</code> in the source image to a rectangle 124 starting at a point <code>dp</code> in the destination, convert the source 125 rectangle into the destination image's co-ordinate space: 126 </p> 127 128 {{code "/doc/progs/image_draw.go" `/RECT/` `/STOP/`}} 129 130 <p> 131 Alternatively: 132 </p> 133 134 {{code "/doc/progs/image_draw.go" `/RECT2/` `/STOP/`}} 135 136 <p> 137 To copy the entire source image, use <code>sr = src.Bounds()</code>. 138 </p> 139 140 <p> 141 <img src="image-2b.png"> 142 </p> 143 144 <p><b>Scrolling an Image</b></p> 145 146 <p> 147 Scrolling an image is just copying an image to itself, with 148 different destination and source rectangles. Overlapping 149 destination and source images are perfectly valid, just as Go's 150 built-in copy function can handle overlapping destination and 151 source slices. To scroll an image m by 20 pixels: 152 </p> 153 154 {{code "/doc/progs/image_draw.go" `/SCROLL/` `/STOP/`}} 155 156 <p><img src="image-2c.png"></p> 157 158 <p><b>Converting an Image to RGBA</b></p> 159 160 <p> 161 The result of decoding an image format might not be an 162 <code>image.RGBA</code>: decoding a GIF results in an <code>image.Paletted</code>, 163 decoding a JPEG results in a <code>ycbcr.YCbCr</code>, and the result of 164 decoding a PNG depends on the image data. To convert any image to 165 an <code>image.RGBA</code>: 166 </p> 167 168 {{code "/doc/progs/image_draw.go" `/CONV/` `/STOP/`}} 169 170 <p> 171 <img src="image-2d.png"> 172 </p> 173 174 <p><b>Drawing Through a Mask</b></p> 175 176 <p> 177 To draw an image through a circular mask with center <code>p</code> and radius 178 <code>r</code>: 179 </p> 180 181 {{code "/doc/progs/image_draw.go" `/CIRCLESTRUCT/` `/STOP/`}} 182 {{code "/doc/progs/image_draw.go" `/CIRCLE2/` `/STOP/`}} 183 184 <p> 185 <img src="image-2e.png"> 186 </p> 187 188 <p><b>Drawing Font Glyphs</b></p> 189 190 <p> 191 To draw a font glyph in blue starting from a point <code>p</code>, draw with 192 an <code>image.Uniform</code> source and an <code>image.Alpha mask</code>. For 193 simplicity, we aren't performing any sub-pixel positioning or 194 rendering, or correcting for a font's height above a baseline. 195 </p> 196 197 {{code "/doc/progs/image_draw.go" `/GLYPH/` `/STOP/`}} 198 199 <p> 200 <img src="image-2f.png"> 201 </p> 202 203 <p><b>Performance</b></p> 204 205 <p> 206 The image/draw package implementation demonstrates how to provide 207 an image manipulation function that is both general purpose, yet 208 efficient for common cases. The <code>DrawMask</code> function takes arguments 209 of interface types, but immediately makes type assertions that its 210 arguments are of specific struct types, corresponding to common 211 operations like drawing one <code>image.RGBA</code> image onto another, or 212 drawing an <code>image.Alpha</code> mask (such as a font glyph) onto an 213 <code>image.RGBA</code> image. If a type assertion succeeds, that type 214 information is used to run a specialized implementation of the 215 general algorithm. If the assertions fail, the fallback code path 216 uses the generic <code>At</code> and <code>Set</code> methods. The fast-paths are purely 217 a performance optimization; the resultant destination image is the 218 same either way. In practice, only a small number of special cases 219 are necessary to support typical applications. 220 </p> 221 222