go - 如何在 gif.Encode() 中使用 golang palette.WebSafe?

标签 go gif

我正在使用 gif.Encode() 对 gif 图像进行编码。根据描述,它使用 palette.Plan9。我想改用 palette.WebSafe

尝试传入 gif.Options 但看起来 Quantizer 是一个接口(interface)。我是否需要编写自己的量化器,或者我能否以某种方式将 WebSafe 指定为内置量化器?

package main

import (
    "bytes"
    "encoding/base64"
    "image/gif"
    "image/png"
    "io"
    "log"
    "strings"
)

const gopher = `iVBORw0KGgoAAAANSUhEUgAAAEsAAAA8CAAAAAALAhhPAAAFfUlEQVRYw62XeWwUVRzHf2+OPbo9d7tsWyiyaZti6eWGAhISoIGKECEKCAiJJkYTiUgTMYSIosYYBBIUIxoSPIINEBDi2VhwkQrVsj1ESgu9doHWdrul7ba73WNm3vOPtsseM9MdwvvrzTs+8/t95ze/33sI5BqiabU6m9En8oNjduLnAEDLUsQXFF8tQ5oxK3vmnNmDSMtrncks9Hhtt/qeWZapHb1ha3UqYSWVl2ZmpWgaXMXGohQAvmeop3bjTRtv6SgaK/Pb9/bFzUrYslbFAmHPp+3WhAYdr+7GN/YnpN46Opv55VDsJkoEpMrY/vO2BIYQ6LLvm0ThY3MzDzzeSJeeWNyTkgnIE5ePKsvKlcg/0T9QMzXalwXMlj54z4c0rh/mzEfr+FgWEz2w6uk8dkzFAgcARAgNp1ZYef8bH2AgvuStbc2/i6CiWGj98y2tw2l4FAXKkQBIf+exyRnteY83LfEwDQAYCoK+P6bxkZm/0966LxcAAILHB56kgD95PPxltuYcMtFTWw/FKkY/6Opf3GGd9ZF+Qp6mzJxzuRSractOmJrH1u8XTvWFHINNkLQLMR+XHXvfPPHw967raE1xxwtA36IMRfkAAG29/7mLuQcb2WOnsJReZGfpiHsSBX81cvMKywYZHhX5hFPtOqPGWZCXnhWGAu6lX91ElKXSalcLXu3UaOXVay57ZSe5f6Gpx7J2MXAsi7EqSp09b/MirKSyJfnfEEgeDjl8FgDAfvewP03zZ+AJ0m9aFRM8eEHBDRKjfcreDXnZdQuAxXpT2NRJ7xl3UkLBhuVGU16gZiGOgZmrSbRdqkILuL/yYoSXHHkl9KXgqNu3PB8oRg0geC5vFmLjad6mUyTKLmF3OtraWDIfACyXqmephaDABawfpi6tqqBZytfQMqOz6S09iWXhktrRaB8Xz4Yi/8gyABDm5NVe6qq/3VzPrcjELWrebVuyY2T7ar4zQyybUCtsQ5Es1FGaZVrRVQwAgHGW2ZCRZshI5bGQi7HesyE972pOSeMM0dSktlzxRdrlqb3Osa6CCS8IJoQQQgBAbTAa5l5epO34rJszibJI8rxLfGzcp1dRosutGeb2VDNgqYrwTiPNsLxXiPi3dz7LiS1WBRBDBOnqEjyy3aQb+/bLiJzz9dIkscVBBLxMfSEac7kO4Fpkngi0ruNBeSOal+u8jgOuqPz12nryMLCniEjtOOOmpt+KEIqsEdocJjYXwrh9OZqWJQyPCTo67LNS/TdxLAv6R5ZNK9npEjbYdT33gRo4o5oTqR34R+OmaSzDBWsAIPhuRcgyoteNi9gF0KzNYWVItPf2TLoXEg+7isNC7uJkgo1iQWOfRSP9NR11RtbZZ3OMG/VhL6jvx+J1m87+RCfJChAtEBQkSBX2PnSiihc/Twh3j0h7qdYQAoRVsRGmq7HU2QRbaxVGa1D6nIOqaIWRjyRZpHMQKWKpZM5feA+lzC4ZFultV8S6T0mzQGhQohi5I8iw+CsqBSxhFMuwyLgSwbghGb0AiIKkSDmGZVmJSiKihsiyOAUs70UkywooYP0bii9GdH4sfr1UNysd3fUyLLMQN+rsmo3grHl9VNJHbbwxoa47Vw5gupIqrZcjPh9R4Nye3nRDk199V+aetmvVtDRE8/+cbgAAgMIWGb3UA0MGLE9SCbWX670TDy1y98c3D27eppUjsZ6fql3jcd5rUe7+ZIlLNQny3Rd+E5Tct3WVhTM5RBCEdiEK0b6B+/ca2gYU393nFj/n1AygRQxPIUA043M42u85+z2SnssKrPl8Mx76NL3E6eXc3be7OD+H4WHbJkKI8AU8irbITQjZ+0hQcPEgId/Fn/pl9crKH02+5o2b9T/eMx7pKoskYgAAAABJRU5ErkJggg==`

func gopherPNG() io.Reader { return base64.NewDecoder(base64.StdEncoding, strings.NewReader(gopher)) }

func main() {
    img, err := png.Decode(gopherPNG())
    if err != nil {
        log.Fatal(err)
    }
    var gifbuf bytes.Buffer
    // Want top use WebSafe palete from https://golang.org/pkg/image/color/palette/
    // Do I need to write my own Quantizer?
    // gif.Options: https://golang.org/pkg/image/gif/#Options
    // Encode Source: https://golang.org/src/image/gif/writer.go?s=10643:10700#L408
    err = gif.Encode(&gifbuf, img, &gif.Options{NumColors: 256})
    if err != nil {
        log.Fatal(err)
    }
}

Playground link

最佳答案

Go 1.12 release notes声明没有 draw.Quantizer 的实现标准库中的接口(interface)。

您可以实现一个,使用第三方就绪的解决方案(例如 thisthis ),或者更简单的解决方案是使用 WebSafe 调色板创建调色板图像,将原始图像绘制到此一个,最后保存调色图像。

这是可以做到的:

// img is your decoded image

pm := image.NewPaletted(img.Bounds(), palette.WebSafe)
draw.Draw(pm, img.Bounds(), img, image.Point{}, draw.Over)
err = gif.Encode(&gifbuf, pm, nil)

注意:如果您使用 draw.Quantizer 并将其传递给 gif.Encode(),内部也会创建一个新的调色图像并使用量化器来计算调色板,然后将旧图像绘制到这个调色板图像上。

关于go - 如何在 gif.Encode() 中使用 golang palette.WebSafe?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56455965/

相关文章:

go - 在 Golang 中禁用数组/slice 边界检查以提高性能

reflection - GO 中运行时类型的新结构实例

rest - 如何在 golang 中使用 julienschmidt/httprouter 传递两个或多个参数?

go - 方法中的值已更改

Python:使用 ffmpeg 生成 .gif 的罕见问题

go - item.(Tweet) 在 Golang 语言中,是什么意思?

java - 如何将 gif 转换为动态壁纸以在 Android 应用程序中使用

ios - 如何在 uiimageview 上显示 ios 照片库 gif

swift - 如何在 SwiftUI 中显示我的 Assets 中的 GIF 图像?

javascript - 即使在运行 document.location =""后,如何确保我的 GIF 保持动画效果