Source:
(1) The Go image package;
(2) The Go image/draw package;
(3) A GIF decoder: an exercise in Go interfaces
Digest:
I. image package:
1. Colors and Color Models:
Color is an interface that defines the minimal method set of any type that can be considered a color: one that can be converted to red, green, blue and alpha values. The conversion may be lossy, such as converting from CMYK or YCbCr color spaces.
A Model is simply something that can convert Colors to other Colors, possibly lossily. For example, the GrayModel can convert any Color to a desaturated Gray. A Palette can convert any Color to one from a limited palette.
2. Points and Rectangles:
A point is an (x,y) co-ordinate on the integer grid, with axes increasing right and down. It is neither a pixel nor a grid square. A Point has no intrinsic width, height or color.
A Rectangle is an axis-aligned rectangle on the integer grid, defined by its top-left and bottom-right Point. A Rectangle also has no intrinsic color. A Rectangle is inclusive at the top-left and exclusive at the bottom-right. For a Point p and a Rectangle r, p.In(r) if and only if r.Min.X <= p.X && p.X < r.Max.X, and similarly for Y. This is analogous to how a slice s[i0:i1] is inclusive at the low end and exclusive at the high end. (Unlike arrays and slices, a Rectangle often has a non-zero origin.)
3. Images:
An Image maps every grid square in a Rectangle to a Color from a Model. "The pixel at (x,y)" refers to the color of the grid square defined by the points (x,y), (x+1,y), (x+1,y+1) and (x,y+1).
The slice-based Image implementations also provide a SubImage method, which returns an Image backed by the same array. Modifying the pixels of a sub-image will affect the pixels of the original image, analogous to how modifying the contents of a sub-slice s[i0:i1] will affect the contents of the original slice's.
For low-level code that works on an image's Pix fields, be aware that ranging over Pix can affect pixels outside an image's bounds. Higher-level code, such as the At and Set methods or the image/draw package, will clip their operations to the image's bounds.
4. Image Formats:
If you have image data of unknown format, the image.Decode function can detect the format. The set of recognized formats is constructed at run time and is not limited to those in the standard package library. An image format package typically registers its format in an init function, and the main package will "underscore import" such a package solely for the side effect of format registration.
II. image/draw package:
Package image/draw defines only one operation: drawing a source image onto a destination image, through an optional mask image.
Composition is performed pixel by pixel in the style of the Plan9 graphics library and the X Render extension. The model is based on the classic "Compositing Digital Images" paper by Porter and Duff, with an additional mask parameter: dst = (src IN mask) OP dst. For a fully opaque mask, this reduces to the original Porter-Duff formula: dst = src OP dst. In Go, a nil mask image is equivalent to an infinitely sized, fully opaque mask image.
The Porter-Duff paper presented 12 different composition operations, but with an explicit mask, only 2 of these are needed in practice: source-over-destination and source. In Go, these operations are represented by the Over and Src constants. The Over operator performs the natural layering of a source image over a destination image: the change to the destination image is smaller where the source (after masking) is more transparent (that is, has lower alpha). The Src operator merely copies the source (after masking) with no regard for the destination image's original content. For fully opaque source and mask images, the two operators produce the same output, but the Src operator is usually faster.
1. Geometric Alignment:(omit, but must-read)
2. Filling a Rectangle:(omit, but must-read)
3. Copying an Image:(omit, but must-read)
4. Scrolling an Image:(omit, but must-read)
5. Converting an Image to RGBA:(omit, but must-read)
6. Drawing Through a Mask:(omit, but must-read)
7. Drawing Font Glyphs:(omit, but must-read)
8. Performance:(omit, but must-read)
9. An example:
package main
import (
"image"
"image/color"
"image/png"
"log"
"os"
)
const width, height = 256, 256
func main() {
// Create a colored image of the given width and height.
img := image.NewNRGBA(image.Rect(0, 0, width, height))
for y := 0; y < height; y ++ {
for x := 0; x < width; x ++ {
img.Set(x, y, color.NRGBA{
R: uint8((x+y)&255),
G: uint8((x+y)<<1&255),
B: uint8((x+y)<<2&255),
A: 255,
})
}
}
f, err := os.Create("/tmp/image.png")
if err != nil {
log.Fatal(err)
}
defer f.Close()
if err := png.Encode(f, img); err != nil {
log.Fatal(err)
}
}
III. A GIF decoder: an exercise in Go interfaces:
An example:
package main
import (
"image"
"image/color"
"image/gif"
"io"
"log"
"math"
"math/rand"
"net/http"
"os"
"time"
)
var palette = []color.Color{color.White, color.Black}
const (
whiteIndex = 0
blackIndex = 1
cycles = 5 // 完整的x振荡器变化的个数
res= 0.001 // 角度分辨率
size = 100 // 图像画布包含[-size...+size]
nframes = 64 // 动画中的帧数
delay = 8 // 以10ms为单位的帧间延迟
)
func lissajous(out io.Writer) {
freq := rand.Float64()*3.0 // y振荡器的相对频率
anim := gif.GIF{LoopCount: nframes}
phase := 0.0 // phase difference
for i := 0; i < nframes; i ++ {
rect := image.Rect(0, 0, 2*size+1, 2*size+1)
img := image.NewPaletted(rect, palette)
for t := 0.0; t < cycles*2*math.Pi; t += res {
x := math.Sin(t)
y := math.Sin(t*freq + phase)
img.SetColorIndex(size+int(x*size+0.5), size+int(y*size+0.5), blackIndex)
}
phase += 0.1
anim.Delay = append(anim.Delay, delay)
anim.Image = append(anim.Image, img)
}
gif.EncodeAll(out, &anim)
}
func main() {
rand.Seed(time.Now().UTC().UnixNano())
if len(os.Args) > 1 && os.Args[0] == "web" {
handler := func(w http.ResponseWriter, r *http.Request) {
lissajous(w)
}
http.HandleFunc("/", handler)
log.Fatal(http.ListenAndServe("localhost:8000", nil))
}
f, err := os.Create("/tmp/anim.gif")
if err != nil {
log.Fatal(err)
}
defer f.Close()
lissajous(f)
}
这篇博客介绍了Go语言中的图像处理包`image`和`image/draw`,包括颜色模型、点和矩形的概念,以及图像的格式解析。`image/draw`包定义了图像绘制操作,如源图像覆盖目的地图像。博客还提供了一个使用Go解码和创建GIF图像的例子,展示了如何生成和写入GIF文件。
1297

被折叠的 条评论
为什么被折叠?



