回到简体

This commit is contained in:
chai2010
2016-02-15 11:06:34 +08:00
parent 9e878f9944
commit 2b37b23285
177 changed files with 2354 additions and 2354 deletions

View File

@@ -1,14 +1,14 @@
## 1.4. GIF動畵
## 1.4. GIF动画
下面的程序演示Go語言標準庫里的image這個package的用法們會用這個包來生成一列的bit-mapped,然後將這些圖片編碼爲一個GIF動畵。我生成的形名字叫利薩如圖形(Lissajous figures)這種效果是在1960年代的老影里出的一種視覺特效。它們是協振子在兩個緯度上振動所産生的麴線,比如兩個sin正波分别在x和y軸輸入會産生的麴線。圖1.1是這樣的一例子:
下面的程序演示Go语言标准库里的image这个package的用法们会用这个包来生成一列的bit-mapped,然后将这些图片编码为一个GIF动画。我生成的形名字叫利萨如图形(Lissajous figures)这种效果是在1960年代的老影里出的一种视觉特效。它们是协振子在两个纬度上振动所产生的曲线,比如两个sin正波分别在x和y轴输入会产生的曲线。图1.1是这样的一例子:
![](../images/ch1-01.png)
譯註:要看這個程序的果,需要將標準輸出重定向到一GIF像文件(使用 `./lissajous > output.gif` 命令。下面是GIF圖像動畵效果:
译注:要看这个程序的果,需要将标准输出重定向到一GIF像文件(使用 `./lissajous > output.gif` 命令。下面是GIF图像动画效果:
![](../images/ch1-01.gif)
段代里我用了一些新的結構包括conststruct結構體類型,複合聲明。和我們舉的其它的例子不太一樣,這一個例子包含了浮點數運算。些概念我們隻在這里簡單地説明一下,之的章節會更詳細地講解。
段代里我用了一些新的结构包括conststruct结构体类型,复合声明。和我们举的其它的例子不太一样,这一个例子包含了浮点数运算。些概念我们只在这里简单地说明一下,之的章节会更详细地讲解。
<u><i>gopl.io/ch1/lissajous</i></u>
```go
@@ -66,25 +66,25 @@ func lissajous(out io.Writer) {
```
當我們import了一包路包含有多個單詞的package比如image/colorimage和color兩個單詞),通常我們隻需要用最後那個單詞表示這個包就可以。所以當我們寫color.White時,這個變量指向的是image/color包里的同理gif.GIF是屬於image/gif包里的量。
当我们import了一包路包含有多个单词的package比如image/colorimage和color两个单词),通常我们只需要用最后那个单词表示这个包就可以。所以当我们写color.White时,这个变量指向的是image/color包里的同理gif.GIF是属于image/gif包里的量。
這個程序里的常量聲明給出了一列的常量值,常量是指在程序編譯後運行時始終都不會變化的值,比如圈數、幀數、延值。常量明和變量聲明一般都會出現在包别,所以些常量在整包中都是可以共享的,或者你也可以把常量明定在函數體內部,那麽這種常量就能在函數體內用。目前常量明的值必是一個數字值、字符串或者一固定的boolean值。
这个程序里的常量声明给出了一列的常量值,常量是指在程序编译后运行时始终都不会变化的值,比如圈数、帧数、延值。常量明和变量声明一般都会出现在包别,所以些常量在整包中都是可以共享的,或者你也可以把常量明定在函数体内部,那么这种常量就能在函数体内用。目前常量明的值必是一个数字值、字符串或者一固定的boolean值。
[]color.Color{...}和gif.GIF{...}這兩個表達式就是我們説的複合聲4.2和4.4.1節有説明)。這是實例化Go言里的複合類型的一種寫法。里的前者生成的是一slice切片者生成的是一struct結構體
[]color.Color{...}和gif.GIF{...}这两个表达式就是我们说的复合声4.2和4.4.1节有说明)。这是实例化Go言里的复合类型的一种写法。里的前者生成的是一slice切片者生成的是一struct结构体
gif.GIF是一struct型(考4.4。struct是一值或者叫字段的集合,不同的型集合在一struct可以讓我們以一個統一的單元進行處理。anim是一gif.GIF型的struct量。這種寫法會生成一struct量,且其內部變量LoopCount字段會被設置爲nframes而其它的字段會被設置爲各自型默的零值。struct部的量可以以一個點(.)來進行訪問,就像在最後兩個賦值語句中式地更新了anim這個struct的Delay和Image字段。
gif.GIF是一struct型(考4.4。struct是一值或者叫字段的集合,不同的型集合在一struct可以让我们以一个统一的单元进行处理。anim是一gif.GIF型的struct量。这种写法会生成一struct量,且其内部变量LoopCount字段会被设置为nframes而其它的字段会被设置为各自型默的零值。struct部的量可以以一个点(.)来进行访问,就像在最后两个赋值语句中式地更新了anim这个struct的Delay和Image字段。
lissajous函數內部有兩層嵌套的for循。外層循環會循環64次每一次都生成一個單獨的動畵幀。它生成了一包含兩種顔色的201&201大小的片,白色和黑色。所有像素點都會被默認設置爲其零值(也就是調色闆palette里的第0值),里我們設置的是白色。每次外層循環都會生成一張新圖片,併將一些像素設置爲黑色。其結果會append到之前果之後。這里我用到了append(考4.2.1)置函數,將結果append到anim中的列表末尾,併設置一個默認的80ms的延值。循環結束後所有的延值被編碼進了GIF片中,併將結果寫入到出流。out這個變量是io.Writer型,這個類型支持把輸出結果寫到很多目,很快我就可以看到例子。
lissajous函数内部有两层嵌套的for循。外层循环会循环64次每一次都生成一个单独的动画帧。它生成了一包含两种颜色的201&201大小的片,白色和黑色。所有像素点都会被默认设置为其零值(也就是调色板palette里的第0值),里我们设置的是白色。每次外层循环都会生成一张新图片,并将一些像素设置为黑色。其结果会append到之前果之后。这里我用到了append(考4.2.1)置函数,将结果append到anim中的列表末尾,并设置一个默认的80ms的延值。循环结束后所有的延值被编码进了GIF片中,并将结果写入到出流。out这个变量是io.Writer型,这个类型支持把输出结果写到很多目,很快我就可以看到例子。
內層循環設置兩個偏振值。x偏振使用sin函。y偏振也是正波,但其相對x軸的偏振是一0-3的隨機值,初始偏振值是一零值,隨着動畵的每一幀逐漸增加。循環會一直跑到x完成五次完整的循。每一步它都會調用SetColorIndex來爲(x, y)點來染黑色。
内层循环设置两个偏振值。x偏振使用sin函。y偏振也是正波,但其相对x轴的偏振是一0-3的随机值,初始偏振值是一零值,随着动画的每一帧逐渐增加。循环会一直跑到x完成五次完整的循。每一步它都会调用SetColorIndex来为(x, y)点来染黑色。
main函數調用lissajous函,用它來向標準輸出流打印信息,所以下面這個命令會像圖1.1中生一GIF動畵
main函数调用lissajous函,用它来向标准输出流打印信息,所以下面这个命令会像图1.1中生一GIF动画
```
$ go build gopl.io/ch1/lissajous
$ ./lissajous >out.gif
```
**練習 1.5** 改前面的Lissajous程序里的調色闆,由黑色改爲緑色。我可以用`color.RGBA{0xRR, 0xGG, 0xBB, 0xff}`得到`#RRGGBB`這個色值,三十六進製的字符串分别代表紅、緑、藍像素。
**练习 1.5** 改前面的Lissajous程序里的调色板,由黑色改为绿色。我可以用`color.RGBA{0xRR, 0xGG, 0xBB, 0xff}`得到`#RRGGBB`这个色值,三十六进制的字符串分别代表红、绿、蓝像素。
**練習 1.6** 改Lissajous程序改其調色闆來生成更富的色,然後脩改SetColorIndex的第三個參數,看看顯示結果吧。
**练习 1.6** 改Lissajous程序改其调色板来生成更富的色,然后修改SetColorIndex的第三个参数,看看显示结果吧。