Golang中加载*.webp图片文件的方法
Golang中加载*.webp图片文件的方法
YouTube(以及由此延伸的 youtube-dl)最近开始提供 *.webp 格式的缩略图,而不是 *.jpg 格式。如果你尝试使用 gdk.PixbufNewFromFile() 函数将 *.webp 文件加载到 gdk.Pixbuf 中,你会收到一个错误:
无法识别文件 "4kberLzSvx0.webp" 的图像文件格式
因此我开始研究 golang.org/x/image/webp 包(https://pkg.go.dev/golang.org/x/image/webp?tab=doc),但我不知道这个包是否就是我应该用来启用 webp 格式支持的,或者如何正确使用它。
这里有人知道如何加载 webp 格式的图像吗?
你可以在以下位置查看我的代码:
Hultan/testWebp
一个尝试加载 *.webp 图像文件的简单程序 - Hultan/testWebp
这是我目前的测试代码:
package main
import (
"fmt"
"github.com/gotk3/gotk3/gdk"
_ "golang.org/x/image/webp"
)
func main() {
// Jpeg 工作正常
loadImage("031wc2m0IWs.jpg")
// Webp 无法工作
loadImage("4kberLzSvx0.webp")
}
func loadImage(path string) *gdk.Pixbuf {
image, err := gdk.PixbufNewFromFile(path)
if err!=nil {
fmt.Printf("%s", err.Error())
}
return image
}
更多关于Golang中加载*.webp图片文件的方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html
如果你只是想启动程序,可以将其保存为临时文件,之后再进行删除…
更多关于Golang中加载*.webp图片文件的方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
好的,现在我有了一张 image.Image,需要将其转换为 gdk.PixBuf,但我似乎做不到。不过这可能是一个更适合 GoTK3 团队的问题,所以感谢你的帮助。
你的意思是将文件像加载任何二进制文件一样加载,然后使用webp包中的decode方法将其转换为Image,再从中转换为PixBuf?我之前没想到可以这样做,但我会尝试一下…
我猜测 gdk.PixbufNewFromFile 并没有使用 Go 的图像加载库,而是使用了它自己的 C 语言版本。
你可以在将图像传递给 gdk 之前,先在 Go 中加载并转换图像格式——这可能是你最好的选择。
我的备用解决方案是,我会做类似的事情(但我会将其保存为 jpg 格式,并保留到用户删除视频为止,而不是立即删除),但我更倾向于直接读取 webp 文件,而不必进行转换。希望 GoTK3 团队能提出一个解决方案,让我无需转换。可能已经有这样的函数了,只是我还不知道。
// 代码部分保持原样
看起来 GdkPixBuf 不支持 webp 图像。请查看 GoTK3 在此处的回复:
[Project question] Loading an webp image file
如果你尝试使用
gdk.PixbufNewFromFile()函数将 *.webp 文件加载到gdk.Pixbuf中,你会收到一个错误:无法识别该图像文件格式…
但也有一些变通方法,包括进行转换,即使用上面提到的包加载图像,然后将其另存为 jpg 格式,正如我们上面讨论的那样。
在Go中加载webp图片需要使用专门的解码包。golang.org/x/image/webp包正是为此设计的,但需要配合标准库的image接口使用。以下是两种解决方案:
方案1:使用golang.org/x/image/webp包
package main
import (
"fmt"
"image"
"os"
"golang.org/x/image/webp"
)
func loadWebPImage(path string) (image.Image, error) {
file, err := os.Open(path)
if err != nil {
return nil, err
}
defer file.Close()
// 使用webp.Decode解码
img, err := webp.Decode(file)
if err != nil {
return nil, err
}
return img, nil
}
func main() {
// 加载webp图片
img, err := loadWebPImage("4kberLzSvx0.webp")
if err != nil {
fmt.Printf("加载失败: %v\n", err)
return
}
// 获取图片尺寸
bounds := img.Bounds()
fmt.Printf("图片尺寸: %dx%d\n", bounds.Dx(), bounds.Dy())
}
方案2:转换为gdk.Pixbuf(如果需要GTK集成)
package main
import (
"bytes"
"fmt"
"image"
"image/png"
"os"
"github.com/gotk3/gotk3/gdk"
"golang.org/x/image/webp"
)
func webpToPixbuf(webpPath string) (*gdk.Pixbuf, error) {
// 1. 打开webp文件
file, err := os.Open(webpPath)
if err != nil {
return nil, err
}
defer file.Close()
// 2. 解码webp
img, err := webp.Decode(file)
if err != nil {
return nil, err
}
// 3. 转换为PNG字节流(gdk支持PNG)
var buf bytes.Buffer
err = png.Encode(&buf, img)
if err != nil {
return nil, err
}
// 4. 从内存数据创建Pixbuf
loader, err := gdk.PixbufLoaderNewWithType("png")
if err != nil {
return nil, err
}
defer loader.Close()
// 写入数据
if ok := loader.Write(buf.Bytes()); !ok {
return nil, fmt.Errorf("写入数据失败")
}
// 获取Pixbuf
pixbuf := loader.GetPixbuf()
return pixbuf, nil
}
func main() {
pixbuf, err := webpToPixbuf("4kberLzSvx0.webp")
if err != nil {
fmt.Printf("转换失败: %v\n", err)
return
}
fmt.Printf("成功加载Pixbuf: %dx%d\n",
pixbuf.GetWidth(), pixbuf.GetHeight())
}
方案3:使用第三方库(如disintegration/imaging)
package main
import (
"fmt"
"github.com/disintegration/imaging"
)
func main() {
// 直接使用imaging库加载webp
img, err := imaging.Open("4kberLzSvx0.webp")
if err != nil {
fmt.Printf("加载失败: %v\n", err)
return
}
fmt.Printf("图片尺寸: %dx%d\n", img.Bounds().Dx(), img.Bounds().Dy())
// 可以保存为其他格式
// err = imaging.Save(img, "output.jpg")
}
关键点说明:
golang.org/x/image/webp包确实用于解码webp格式,但它返回的是image.Image接口- GTK的
gdk.PixbufNewFromFile()内部使用GDK的图片加载器,默认不支持webp - 需要先将webp解码,然后转换为GDK支持的格式(如PNG、JPEG)
- 如果使用
golang.org/x/image/webp,确保导入时带下划线:_ "golang.org/x/image/webp"用于注册解码器
选择哪种方案取决于你的具体需求。如果只需要在Go中处理图片,方案1最简单;如果需要与GTK集成,方案2更合适。

