Golang image/gif编码全部都有许多黑点

sd2nnvve  于 2022-12-07  发布在  Go
关注(0)|答案(2)|浏览(173)

我有许多png图像,并希望将它们编码为gif动画。
这些png图像没有任何黑点,但gif结果有许多点。

g := new(gif.GIF)
    frames := len(images)
    g.Image = make([]*image.Paletted, frames)
    g.Delay = make([]int, frames)
    eg := errgroup.Group{}
    var cl color.Palette = palette.Plan9
    for k, img := range images {
        img := img
        k := k
        eg.Go(func() error {
            Paletted := image.NewPaletted(img.Bounds(), cl)
            draw.FloydSteinberg.Draw(Paletted, img.Bounds(), img, image.Point{})
            g.Image[k] = Paletted
            g.Delay[k] = deply
            return nil
        })
    }
    if err := eg.Wait(); err != nil {
        return nil, err
    }
    var buf bytes.Buffer
    err := gif.EncodeAll(&buf, g)

原点png:x1c 0d1x
使用编号:

我png信息:
文件类型:PNG
文件类型扩展名:石油天然气
MIME类型:图像/png
位深度:8
颜色类型:带Alpha的RGB
压缩:放气/充气
过滤器:自适应
隔行:非隔行
SRGB渲染:感知
Exif字节顺序:大字节序(Motorola,MM)
色彩空间:sRGB
带有黑点的gif:

已使用palgen。生成(img,256):

mwngjboj

mwngjboj1#

GIF使用256色调色板,而PNG通常是RGBA,每个颜色通道至少8位(和alpha)。在不完整的示例代码中,使用了预定义的palette.Plan9调色板。在原始PNG中选取至少最主要的颜色表明它是RGB颜色#f08740。但是在Plan9调色板中没有匹配的颜色。因此FloydSteinberg必须使用Plan9调色板中“最接近”的颜色进行抖动。
你需要使用一个合适的调色板来避免抖动,或者至少最小化它。因为你给出了一个非最小化和不完整的例子,我不得不推出一个最小化的例子,为GIF创建一个定制的调色板,基于唯一的PNG源(请,下次上传 * 单独 * 的图像,不要把所有的东西放在一个单一的图像,这使得事情真的很不方便)。
快速的google搜索会发现Go模块github.com/xyproto/palgen,它确实会根据输入图像和指定的颜色数创建一个定制的color.Palette;这个模块似乎被积极地维护着,我在使用它时立即获得了成功:

img, _, err := image.Decode(f)
pal, err := palgen.Generate(img, 256)

下面是一个完整的例子,它为我生成了一个合适的GIF(gif.gif),没有抖动,给出了一个source.png的源PNG:

package main

import (
    "image"
    "image/draw"
    "image/gif"
    _ "image/png"
    "os"

    "github.com/xyproto/palgen"
)

func main() {
    g := new(gif.GIF)
    g.Image = make([]*image.Paletted, 1)
    g.Delay = make([]int, 1)

    f, err := os.Open("source.png")
    if err != nil {
        panic(err)
    }
    defer f.Close()
    img, _, err := image.Decode(f)
    pal, err := palgen.Generate(img, 256)

    Paletted := image.NewPaletted(img.Bounds(), pal)
    draw.FloydSteinberg.Draw(Paletted, img.Bounds(), img, image.Point{})
    g.Image[0] = Paletted
    g.Delay[0] = 100

    out, err := os.Create("gif.gif")
    if err != nil {
        panic(err)
    }
    defer out.Close()
    err = gif.EncodeAll(out, g)
    if err != nil {
        panic(err)
    }
}

源图像source.png

最终GIF格式gif.gif

tvokkenx

tvokkenx2#

用途:draw.Draw(Paletted,img.Bounds(),img,image.ZP, draw.Src)
替换:draw.FloydSteinberg.Draw(Paletted, img.Bounds(), img, image.Point{})

相关问题