为了账号安全,请及时绑定邮箱和手机立即绑定

如何循环旋转图像以在 golang 中创建 GIF?

如何循环旋转图像以在 golang 中创建 GIF?

Go
侃侃尔雅 2022-12-19 19:23:22
我想循环重复旋转图像,以便使用 Go 的各种图像处理工具创建 GIF,但我似乎无法弄清楚我做错了什么。此处,Gwenview 报告生成的 GIF 不是动画,并且仅包含一帧。package mainimport (    "image"    "image/color/palette"    "image/color"    "image/gif"    "image/draw"    "io"    "os"    "github.com/disintegration/imaging")func main() {    rotate(os.Stdout)}func rotate(out io.Writer) {    f, _ := os.Open("myimage.png")    defer f.Close()    base, _, _ := image.Decode(f)    const (        rot     = 45    // degrees        nframes = 5    // number of animation frames        delay   = 20     // delay between frames in 10ms units    )    bounds  := base.Bounds()    anim := gif.GIF{LoopCount: nframes}    for i := 0; i < nframes; i++ {        img := imaging.Rotate(base, float64(360 - (rot * i)), color.Transparent)        bounds = img.Bounds()        palettedImg := image.NewPaletted(bounds, palette.Plan9)        draw.Draw(palettedImg, bounds, img, bounds.Min, draw.Src)        anim.Delay = append(anim.Delay, delay)        anim.Image = append(anim.Image, palettedImg)    }    gif.EncodeAll(out, &anim) // NOTE: ignoring encoding errors}
查看完整描述

2 回答

?
芜湖不芜

TA贡献1796条经验 获得超7个赞

问题确实是您忽略了错误消息。永远不要那样做,始终准确地处理错误!在您的特定情况下,您的示例不起作用,因为您将新创建的图像边界设置为原始图像,但是因为在每个帧迭代中您都在旋转图像,所以它们的尺寸超出了原始边界。如果您没有忽略编码错误,您可以捕捉到问题所在。


err := gif.EncodeAll(out, &anim)

if err != nil {

    fmt.Printf("%v", err)

}

错误:


$ gif: image block is out of bounds  


查看完整回答
反对 回复 2022-12-19
?
慕斯709654

TA贡献1840条经验 获得超5个赞

这是我用来制作一个gif. 也许它可以帮助您找到解决方案。


package main


import (

    "fmt"

    "image"

    "image/color"

    "image/gif"

    "math"

    "os"

)


type Circle struct {

    X, Y, R float64

}


func (c *Circle) Brightness(x, y float64) uint8 {

    var dx, dy float64 = c.X - x, c.Y - y

    d := math.Sqrt(dx*dx+dy*dy) / c.R

    if d > 1 {

        return 0

    } else {

        return 255

    }

}


func main() {

    var w, h int = 240, 240


    var palette = []color.Color{

        color.RGBA{0x00, 0x00, 0x00, 0xff}, color.RGBA{0x00, 0x00, 0xff, 0xff},

        color.RGBA{0x00, 0xff, 0x00, 0xff}, color.RGBA{0x00, 0xff, 0xff, 0xff},

        color.RGBA{0xff, 0x00, 0x00, 0xff}, color.RGBA{0xff, 0x00, 0xff, 0xff},

        color.RGBA{0xff, 0xff, 0x00, 0xff}, color.RGBA{0xff, 0xff, 0xff, 0xff},

    }

    var images []*image.Paletted

    var delays []int


    var hw, hh float64 = float64(w / 2), float64(h / 2)

    circles := []*Circle{&Circle{}, &Circle{}, &Circle{}}

    steps := 20

    // Set up for the animtion loop 

    for step := 0; step < steps; step++ {

        img := image.NewPaletted(image.Rect(0, 0, w, h), palette)

        images = append(images, img)

        delays = append(delays, 0)


        θ := 2.0 * math.Pi / float64(steps) * float64(step)

        for i, circle := range circles {

            θ0 := 2 * math.Pi / 3 * float64(i)

            circle.X = hw - 40*math.Sin(θ0) - 20*math.Sin(θ0+θ)

            circle.Y = hh - 40*math.Cos(θ0) - 20*math.Cos(θ0+θ)

            circle.R = 50

        }


        for x := 0; x < w; x++ {

            for y := 0; y < h; y++ {

                img.Set(x, y, color.RGBA{

                    circles[0].Brightness(float64(x), float64(y)),

                    circles[1].Brightness(float64(x), float64(y)),

                    circles[2].Brightness(float64(x), float64(y)),

                    255,

                })

            }

        }

    }


    f, err := os.OpenFile("rgb.gif", os.O_WRONLY|os.O_CREATE, 0600)

    if err != nil {

        fmt.Println(err)

        return

    }

    defer f.Close()

    gif.EncodeAll(f, &gif.GIF{

        Image: images,

        Delay: delays,

    })

}

TLDR;请参阅要点以获取完整示例

感谢nitoyon


查看完整回答
反对 回复 2022-12-19
  • 2 回答
  • 0 关注
  • 96 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信