Go程序设计语言1.4 GIF动画

简介:

1.4 GIF动画


下一个程序展示Go标准的图像包的使用,用来创建一系列的位图图像,然后将位图序列编码为GIF动画。下面的图像叫作利萨茹图形,是20世纪60年代科幻片中的纤维状视觉效果。利萨茹图形是参数化的二维谐振曲线,如示波器x轴和y轴馈电输入的两个正弦波。图1-1是几个示例。

 

图1-1 四种利萨茹图形

这段代码里有几个新的组成,包括const声明、结构体以及复合字面量。不像大多数例子,本例还引入了浮点运算。这个示例的主要目的是提供一些思路,表明Go语言看起来是怎样的,以及利用Go语言和它的库可以轻易完成哪些事情,这里只简短地讨论这几个主题,更多细节将放在后面章节。

 

 

    rand.Seed(time.Now().UTC().UnixNano())

    if len(os.Args) > 1 && os.Args[1] == "web" {

            handler := func(w http.ResponseWriter, r *http.Request) {

                lissajous(w)

            }

            http.HandleFunc("/", handler)

            log.Fatal(http.ListenAndServe("localhost:8000", nil))

            return

    }

 

 

在导入那些由多段路径如image/color组成的包之后,使用路径最后的一段来引用这个包。所以变量color.White属于image/color包,gif.GIF属于image/gif包。

const声明(参考3.6节)用来给常量命名,常量是其值在编译期间固定的量,例如周期、帧数和延迟等数值参数。与var声明类似,const声明可以出现在包级别(所以这些常量名字在包生命周期内都是可见的)或在一个函数内(所以名字仅在函数体内可见)。常量必须是数字、字符串或布尔值。

表达式[]color.Color{...}和gif.GIF{...}是复合字面量(参考4.2节、4.4.1节),即用一系列元素的值初始化Go的复合类型的紧凑表达方式。这里,第一个是slice,第二个是结构体。

gif.GIF是一个结构体类型(参考4.4节)。结构体由一组称为字段的值组成,字段通常有不同的数据类型,它们一起组成单个对象,作为一个单位被对待。anim变量是gif.GIF结构体类型。这个结构体字面量创建一个结构体LoopCount,其值设置为nframes;其他字段的值是对应类型的零值。结构体的每个字段可以通过点记法来访问,在最后两个赋值语句中,显式更新anim结构体的Delay和Image字段。

lissajous函数有两个嵌套的循环。外层有64个迭代,每个迭代产生一个动画帧。它创建一个201×201大小的画板,使用黑和白两种颜色。所有的像素值默认设置为0(画板中的初始化颜色),这里设置为白色。每一个内层循环通过设置一些像素为黑色产生一个新的图像。结果使用内置的append参数将其追加到anim的帧列表中,并且指定80ms的延迟。最后帧和延迟的序列被编码成GIF格式,然后写入输出流out。out的类型是io.Writer,它可以帮我们输出到很多地方,稍后即可看到。

外层循环运行两个振荡器。x方向的振荡器是正弦函数,y方向也是正弦化的,但是它的频率相对于x的振动周期是0~3之间的一个随机数,它的相位相对于x的初始值为0,然后随着每个动画帧增加。该循环在x振荡器完成5个完整周期后停止。每一步它都调用SetColorIndex将对应画板上面的(x, y)位置涂为黑色,在画板上的值为1。

main函数调用lissajous函数,直接写到标准输出,所以这个命令产生一个像图1-1那样的GIF动画:

 

练习1.5:改变利萨茹程序的画板颜色为绿色黑底来增加真实性。使用color.RGBA {0xRR,0xGG,0xBB,0xff}创建一种Web颜色#RRGGBB,每一对十六进制数字表示组成一个像素红、绿、蓝分量的亮度。

练习1.6:通过在画板中添加更多颜色,然后通过有趣的方式改变SetColorIndex的第三个参数,修改利萨茹程序来产生多种色彩的图片。

相关文章
|
5月前
|
存储 Go 图形学
如何使用 Go 语言来实现 GIF 动画?
如何使用 Go 语言来实现 GIF 动画?
81 0