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 格式的图像吗?

你可以在以下位置查看我的代码:

GitHub GitHub

头像

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

7 回复

如果你只是想启动程序,可以将其保存为临时文件,之后再进行删除…

更多关于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 在此处的回复:

github.com/gotk3/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")
}

关键点说明:

  1. golang.org/x/image/webp包确实用于解码webp格式,但它返回的是image.Image接口
  2. GTK的gdk.PixbufNewFromFile()内部使用GDK的图片加载器,默认不支持webp
  3. 需要先将webp解码,然后转换为GDK支持的格式(如PNG、JPEG)
  4. 如果使用golang.org/x/image/webp,确保导入时带下划线:_ "golang.org/x/image/webp"用于注册解码器

选择哪种方案取决于你的具体需求。如果只需要在Go中处理图片,方案1最简单;如果需要与GTK集成,方案2更合适。

回到顶部