Go生成的动画GIF在Windows中不起作用 [英] Go-generated animated GIFs didn't work in windows
问题描述
我发现一个示例在Windows中无法正常运行. 该程序演示了Go的标准图像包的基本用法,我们将使用它们创建位图图像序列,然后将该序列编码为GIF动画.
I found an example didn't work properly in Windows. This program demonstrates basic usage of Go's standard image packages, which we'll use to create a sequence of bit-mapped images and then encode the sequence as a GIF animation.
package main
import (
"image"
"image/color"
"image/gif"
"io"
"math"
"math/rand"
"os"
)
import (
"log"
"net/http"
"time"
)
//!+main
var palette = []color.Color{color.White, color.Black}
const (
whiteIndex = 0 // first color in palette
blackIndex = 1 // next color in palette
)
func main() {
//!-main
// The sequence of images is deterministic unless we seed
// the pseudo-random number generator using the current time.
// Thanks to Randall McPherson for pointing out the omission.
rand.Seed(time.Now().UTC().UnixNano())
if len(os.Args) > 1 && os.Args[1] == "web" {
//!+http
handler := func(w http.ResponseWriter, r *http.Request) {
lissajous(w)
}
http.HandleFunc("/", handler)
//!-http
log.Fatal(http.ListenAndServe("localhost:8000", nil))
return
}
//!+main
lissajous(os.Stdout)
}
func lissajous(out io.Writer) {
const (
cycles = 5 // number of complete x oscillator revolutions
res = 0.001 // angular resolution
size = 100 // image canvas covers [-size..+size]
nframes = 64 // number of animation frames
delay = 8 // delay between frames in 10ms units
)
freq := rand.Float64() * 3.0 // relative frequency of y oscillator
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) // NOTE: ignoring encoding errors
}
但是,如果我在Windows Power Shell中运行该代码,则该代码可以在cmd中正常运行
The code runs properly in cmd, however, if I run it in Windows Power Shell like:
.\lissajous.exe >out.gif
out.gif无法打开,我也不知道为什么.
The out.gif can't be opened and I don't know why.
推荐答案
GIF文件(gif数据)是二进制格式,而不是文本格式.尝试将其写入标准输出并将其重定向到文件可能会遭受转换.例如,Windows PowerShell最有可能转换一些控制字符(例如"\n"
到"\r\n"
),因此生成的二进制文件将与
The GIF file (the gif data) is a binary format, not textual. Attempting to write it to the standard output and redirecting that to a file may suffer transformations. For example, the Windows PowerShell most likely converts some control characters (like "\n"
to "\r\n"
), so the resulting binary will not be identical to what gif.EncodeAll()
writes to the standard output. Apparently cmd.exe
does not do such transformations.
我建议直接写入文件(您可以将 os.File
传递为输出),或可以使用 ioutil.WriteFile()
转储到文件的内存缓冲区.
I recommend writing to a file directly (you may pass an os.File
as the output), or an in-memory buffer which you can dump to a file using ioutil.WriteFile()
.
这是直接写入文件的样子:
Here's how writing directly to a file could look like:
f, err := os.Create("a.gif")
if err != nil {
panic(err)
}
defer f.Close()
lissajous(f)
这是内存中解决方案的样子:
Here's how the in-memory solution could look like:
buf := &bytes.Buffer{}
lissajous(buf)
if err := ioutil.WriteFile("a.gif", buf.Bytes(), 0666); err != nil {
panic(err)
}
查看相关问题:图片/gif:EncodeAll的结果在GNOME的眼睛中不可见
仍有一些应用程序无法读取结果的可能性(请参见上面的问题),可以通过使用以下命令将输出图像转换为unix来解决:
There is still a chance the result won't be readable by some apps (see above issue), which can be fixed by converting the output image in unix with the following command:
convert original.gif -coalesce unoptimized.gif
来源:修复无法打开动画GIF图像,但是Firefox和ImageMagick可以
这篇关于Go生成的动画GIF在Windows中不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!