github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/doc/articles/image_package.html (about)

     1  <!--{
     2  	"Title": "The Go image package",
     3  	"Template": true
     4  }-->
     5  
     6  <p>
     7  The <a href="/pkg/image/">image</a> and
     8  <a href="/pkg/image/color/">image/color</a> packages define a number of types:
     9  <code>color.Color</code> and <code>color.Model</code> describe colors,
    10  <code>image.Point</code> and <code>image.Rectangle</code> describe basic 2-D
    11  geometry, and <code>image.Image</code> brings the two concepts together to
    12  represent a rectangular grid of colors. A
    13  <a href="/doc/articles/image_draw.html">separate article</a> covers image
    14  composition with the <a href="/pkg/image/draw/">image/draw</a> package.
    15  </p>
    16  
    17  <p>
    18  <b>Colors and Color Models</b>
    19  </p>
    20  
    21  <p>
    22  <a href="/pkg/image/color/#Color">Color</a> is an interface that defines the minimal
    23  method set of any type that can be considered a color: one that can be converted
    24  to red, green, blue and alpha values. The conversion may be lossy, such as
    25  converting from CMYK or YCbCr color spaces.
    26  </p>
    27  
    28  {{code "/src/pkg/image/color/color.go" `/type Color interface/` `/^}/`}}
    29  
    30  <p>
    31  There are three important subtleties about the return values. First, the red,
    32  green and blue are alpha-premultiplied: a fully saturated red that is also 25%
    33  transparent is represented by RGBA returning a 75% r. Second, the channels have
    34  a 16-bit effective range: 100% red is represented by RGBA returning an r of
    35  65535, not 255, so that converting from CMYK or YCbCr is not as lossy. Third,
    36  the type returned is <code>uint32</code>, even though the maximum value is 65535, to
    37  guarantee that multiplying two values together won't overflow. Such
    38  multiplications occur when blending two colors according to an alpha mask from a
    39  third color, in the style of
    40  <a href="https://en.wikipedia.org/wiki/Alpha_compositing">Porter and Duff's</a>
    41  classic algebra:
    42  </p>
    43  
    44  <pre>
    45  dstr, dstg, dstb, dsta := dst.RGBA()
    46  srcr, srcg, srcb, srca := src.RGBA()
    47  _, _, _, m := mask.RGBA()
    48  const M = 1&lt;&lt;16 - 1
    49  // The resultant red value is a blend of dstr and srcr, and ranges in [0, M].
    50  // The calculation for green, blue and alpha is similar.
    51  dstr = (dstr*(M-m) + srcr*m) / M
    52  </pre>
    53  
    54  <p>
    55  The last line of that code snippet would have been more complicated if we worked
    56  with non-alpha-premultiplied colors, which is why <code>Color</code> uses
    57  alpha-premultiplied values.
    58  </p>
    59  
    60  <p>
    61  The image/color package also defines a number of concrete types that implement
    62  the <code>Color</code> interface. For example,
    63  <a href="/pkg/image/color/#RGBA"><code>RGBA</code></a> is a struct that represents
    64  the classic "8 bits per channel" color.
    65  </p>
    66  
    67  {{code "/src/pkg/image/color/color.go" `/type RGBA struct/` `/^}/`}}
    68  
    69  <p>
    70  Note that the <code>R</code> field of an <code>RGBA</code> is an 8-bit
    71  alpha-premultiplied color in the range [0, 255]. <code>RGBA</code> satisfies the
    72  <code>Color</code> interface by multiplying that value by 0x101 to generate a
    73  16-bit alpha-premultiplied color in the range [0, 65535]. Similarly, the
    74  <a href="/pkg/image/color/#NRGBA"><code>NRGBA</code></a> struct type represents
    75  an 8-bit non-alpha-premultiplied color, as used by the PNG image format. When
    76  manipulating an <code>NRGBA</code>'s fields directly, the values are
    77  non-alpha-premultiplied, but when calling the <code>RGBA</code> method, the
    78  return values are alpha-premultiplied.
    79  </p>
    80  
    81  <p>
    82  A <a href="/pkg/image/color/#Model"><code>Model</code></a> is simply
    83  something that can convert <code>Color</code>s to other <code>Color</code>s, possibly lossily. For
    84  example, the <code>GrayModel</code> can convert any <code>Color</code> to a
    85  desaturated <a href="/pkg/image/color/#Gray"><code>Gray</code></a>. A
    86  <code>Palette</code> can convert any <code>Color</code> to one from a
    87  limited palette.
    88  </p>
    89  
    90  {{code "/src/pkg/image/color/color.go" `/type Model interface/` `/^}/`}}
    91  
    92  {{code "/src/pkg/image/color/color.go" `/type Palette \[\]Color/`}}
    93  
    94  <p>
    95  <b>Points and Rectangles</b>
    96  </p>
    97  
    98  <p>
    99  A <a href="/pkg/image/#Point"><code>Point</code></a> is an (x, y) co-ordinate
   100  on the integer grid, with axes increasing right and down. It is neither a pixel
   101  nor a grid square. A <code>Point</code> has no intrinsic width, height or
   102  color, but the visualizations below use a small colored square.
   103  </p>
   104  
   105  {{code "/src/pkg/image/geom.go" `/type Point struct/` `/^}/`}}
   106  
   107  <p>
   108  <img src="image-package-01.png" width="400" height="300">
   109  </p>
   110  
   111  {{code "/doc/progs/image_package1.go" `/p := image.Point/`}}
   112  
   113  <p>
   114  A <a href="/pkg/image/#Rectangle"><code>Rectangle</code></a> is an axis-aligned
   115  rectangle on the integer grid, defined by its top-left and bottom-right
   116  <code>Point</code>.  A <code>Rectangle</code> also has no intrinsic color, but
   117  the visualizations below outline rectangles with a thin colored line, and call
   118  out their <code>Min</code> and <code>Max</code> <code>Point</code>s.
   119  </p>
   120  
   121  {{code "/src/pkg/image/geom.go" `/type Rectangle struct/` `/^}/`}}
   122  
   123  <p>
   124  For convenience, <code>image.Rect(x0, y0, x1, y1)</code> is equivalent to
   125  <code>image.Rectangle{image.Point{x0, y0}, image.Point{x1, y1}}</code>, but is
   126  much easier to type.
   127  </p>
   128  
   129  <p>
   130  A <code>Rectangle</code> is inclusive at the top-left and exclusive at the
   131  bottom-right. For a <code>Point p</code> and a <code>Rectangle r</code>,
   132  <code>p.In(r)</code> if and only if
   133  <code>r.Min.X &lt;= p.X &amp;&amp; p.X &lt; r.Max.X</code>, and similarly for <code>Y</code>. This is analogous to how
   134  a slice <code>s[i0:i1]</code> is inclusive at the low end and exclusive at the
   135  high end. (Unlike arrays and slices, a <code>Rectangle</code> often has a
   136  non-zero origin.)
   137  </p>
   138  
   139  <p>
   140  <img src="image-package-02.png" width="400" height="300">
   141  </p>
   142  
   143  {{code "/doc/progs/image_package2.go" `/r := image.Rect/` `/fmt.Println/`}}
   144  
   145  <p>
   146  Adding a <code>Point</code> to a <code>Rectangle</code> translates the
   147  <code>Rectangle</code>. Points and Rectangles are not restricted to be in the
   148  bottom-right quadrant.
   149  </p>
   150  
   151  <p>
   152  <img src="image-package-03.png" width="400" height="300">
   153  </p>
   154  
   155  {{code "/doc/progs/image_package3.go" `/r := image.Rect/` `/fmt.Println/`}}
   156  
   157  <p>
   158  Intersecting two Rectangles yields another Rectangle, which may be empty.
   159  </p>
   160  
   161  <p>
   162  <img src="image-package-04.png" width="400" height="300">
   163  </p>
   164  
   165  {{code "/doc/progs/image_package4.go" `/r := image.Rect/` `/fmt.Printf/`}}
   166  
   167  <p>
   168  Points and Rectangles are passed and returned by value. A function that takes a
   169  <code>Rectangle</code> argument will be as efficient as a function that takes
   170  two <code>Point</code> arguments, or four <code>int</code> arguments.
   171  </p>
   172  
   173  <p>
   174  <b>Images</b>
   175  </p>
   176  
   177  <p>
   178  An <a href="/pkg/image/#Image">Image</a> maps every grid square in a
   179  <code>Rectangle</code> to a <code>Color</code> from a <code>Model</code>.
   180  "The pixel at (x, y)" refers to the color of the grid square defined by the
   181  points (x, y), (x+1, y), (x+1, y+1) and (x, y+1).
   182  </p>
   183  
   184  {{code "/src/pkg/image/image.go" `/type Image interface/` `/^}/`}}
   185  
   186  <p>
   187  A common mistake is assuming that an <code>Image</code>'s bounds start at (0,
   188  0). For example, an animated GIF contains a sequence of Images, and each
   189  <code>Image</code> after the first typically only holds pixel data for the area
   190  that changed, and that area doesn't necessarily start at (0, 0). The correct
   191  way to iterate over an <code>Image</code> m's pixels looks like:
   192  </p>
   193  
   194  <pre>
   195  b := m.Bounds()
   196  for y := b.Min.Y; y &lt; b.Max.Y; y++ {
   197  	for x := b.Min.X; x &lt; b.Max.X; x++ {
   198  		doStuffWith(m.At(x, y))
   199  	}
   200  }
   201  </pre>
   202  
   203  <p>
   204  <code>Image</code> implementations do not have to be based on an in-memory
   205  slice of pixel data. For example, a
   206  <a href="/pkg/image/#Uniform"><code>Uniform</code></a> is an
   207  <code>Image</code> of enormous bounds and uniform color, whose in-memory
   208  representation is simply that color.
   209  </p>
   210  
   211  {{code "/src/pkg/image/names.go" `/type Uniform struct/` `/^}/`}}
   212  
   213  <p>
   214  Typically, though, programs will want an image based on a slice. Struct types
   215  like <a href="/pkg/image/#RGBA"><code>RGBA</code></a> and
   216  <a href="/pkg/image/#Gray"><code>Gray</code></a> (which other packages refer
   217  to as <code>image.RGBA</code> and <code>image.Gray</code>) hold slices of pixel
   218  data and implement the <code>Image</code> interface.
   219  </p>
   220  
   221  {{code "/src/pkg/image/image.go" `/type RGBA struct/` `/^}/`}}
   222  
   223  <p>
   224  These types also provide a <code>Set(x, y int, c color.Color)</code> method
   225  that allows modifying the image one pixel at a time.
   226  </p>
   227  
   228  {{code "/doc/progs/image_package5.go" `/m := image.New/` `/m.Set/`}}
   229  
   230  <p>
   231  If you're reading or writing a lot of pixel data, it can be more efficient, but
   232  more complicated, to access these struct type's <code>Pix</code> field directly.
   233  </p>
   234  
   235  <p>
   236  The slice-based <code>Image</code> implementations also provide a
   237  <code>SubImage</code> method, which returns an <code>Image</code> backed by the
   238  same array. Modifying the pixels of a sub-image will affect the pixels of the
   239  original image, analogous to how modifying the contents of a sub-slice
   240  <code>s[i0:i1]</code> will affect the contents of the original slice
   241  <code>s</code>.
   242  </p>
   243  
   244  <img src="image-package-05.png" width="400" height="300">
   245  
   246  {{code "/doc/progs/image_package6.go" `/m0 := image.New/` `/fmt.Println\(m0.Stride/`}}
   247  
   248  <p>
   249  For low-level code that works on an image's <code>Pix</code> field, be aware
   250  that ranging over <code>Pix</code> can affect pixels outside an image's bounds.
   251  In the example above, the pixels covered by <code>m1.Pix</code> are shaded in
   252  blue. Higher-level code, such as the <code>At</code> and <code>Set</code>
   253  methods or the <a href="/pkg/image/draw/">image/draw package</a>, will clip
   254  their operations to the image's bounds.
   255  </p>
   256  
   257  <p>
   258  <b>Image Formats</b>
   259  </p>
   260  
   261  <p>
   262  The standard package library supports a number of common image formats, such as
   263  GIF, JPEG and PNG. If you know the format of a source image file, you can
   264  decode from an <a href="/pkg/io/#Reader"><code>io.Reader</code></a> directly.
   265  </p>
   266  
   267  <pre>
   268  import (
   269  	"image/jpeg"
   270  	"image/png"
   271  	"io"
   272  )
   273  
   274  // convertJPEGToPNG converts from JPEG to PNG.
   275  func convertJPEGToPNG(w io.Writer, r io.Reader) error {
   276  	img, err := jpeg.Decode(r)
   277  	if err != nil {
   278  		return err
   279  	}
   280  	return png.Encode(w, img)
   281  }
   282  </pre>
   283  
   284  <p>
   285  If you have image data of unknown format, the
   286  <a href="/pkg/image/#Decode"><code>image.Decode</code></a> function can detect
   287  the format. The set of recognized formats is constructed at run time and is not
   288  limited to those in the standard package library. An image format package
   289  typically registers its format in an init function, and the main package will
   290  "underscore import" such a package solely for the side effect of format
   291  registration.
   292  </p>
   293  
   294  <pre>
   295  import (
   296  	"image"
   297  	"image/png"
   298  	"io"
   299  
   300  	_ "code.google.com/p/vp8-go/webp"
   301  	_ "image/jpeg"
   302  )
   303  
   304  // convertToPNG converts from any recognized format to PNG.
   305  func convertToPNG(w io.Writer, r io.Reader) error {
   306  	img, _, err := image.Decode(r)
   307  	if err != nil {
   308  		return err
   309  	}
   310  	return png.Encode(w, img)
   311  }
   312  </pre>