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