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<<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 <= p.X && p.X < 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 < b.Max.Y; y++ { 197 for x := b.Min.X; x < 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>