Golang生成WebP格式文件的缩略图实现方法
Golang生成WebP格式文件的缩略图实现方法
以下代码使用 github.com/disintegration/imaging 包来创建缩略图,对于典型的图像格式(如 JPEG)效果很好,但对于 webp 文件格式则效果不佳。
使用下面的代码时,我遇到了错误 imaging: unsupported image format。
是否有更健壮的方法来为典型图像类型(jpg、gif、tiff、bmp 等)和 webp 生成缩略图?
package main
import (
"bytes"
"fmt"
"github.com/disintegration/imaging"
"github.com/chai2010/webp"
"io/ioutil"
)
//https://stackoverflow.com/questions/8340751/webp-encoder-decoder-in-go
func main() {
//img, _ := imaging.Open("ml/input/apple.jpg")
// Load webp
data, _ := ioutil.ReadFile("ml/input/waterski2.webp")
// Decode webp
img, _ := webp.Decode(bytes.NewReader(data))
//Create thumbnail
dstImage := imaging.Thumbnail(img, 400, 400, imaging.Lanczos)
err1:=imaging.Save(dstImage, "ml/output/waterski2.webp")
if err1!=nil{
fmt.Println(err1)
}
}
更多关于Golang生成WebP格式文件的缩略图实现方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于Golang生成WebP格式文件的缩略图实现方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
是的,你可能是对的。我对图像格式的编码/解码了解不够深入,无法断定这个包是否可用于转换。
不过,我要辩解一下,看起来那是大约一周前发布的 0.0.0 版本,所以我之前并不知道它 😊
只要我有时间,我一定会为我的项目研究一下它。至于它是否对 @jack1234 有帮助,我就不知道了。
据我所知,Go 语言目前尚未支持 WEBP 格式。我最终通过调用外部程序 dwebp(Linux 系统)来将 WEBP 转换为 JPG 或 PNG。它很可能也可以用于反向转换。我相信在 Windows 或 Mac 系统上也存在类似的程序。
对于WebP格式的缩略图生成,imaging包确实存在格式支持限制。以下是更健壮的实现方法,支持包括WebP在内的多种图像格式:
package main
import (
"bytes"
"fmt"
"image"
"image/gif"
"image/jpeg"
"image/png"
"os"
"path/filepath"
"strings"
"github.com/disintegration/imaging"
"golang.org/x/image/bmp"
"golang.org/x/image/tiff"
"github.com/chai2010/webp"
)
// 支持的图像格式解码器映射
var decoders = map[string]func([]byte) (image.Image, error){
".jpg": decodeJPEG,
".jpeg": decodeJPEG,
".png": decodePNG,
".gif": decodeGIF,
".bmp": decodeBMP,
".tiff": decodeTIFF,
".tif": decodeTIFF,
".webp": decodeWebP,
}
// 支持的图像格式编码器映射
var encoders = map[string]func(string, image.Image) error{
".jpg": encodeJPEG,
".jpeg": encodeJPEG,
".png": encodePNG,
".gif": encodeGIF,
".bmp": encodeBMP,
".tiff": encodeTIFF,
".tif": encodeTIFF,
".webp": encodeWebP,
}
// 解码函数实现
func decodeJPEG(data []byte) (image.Image, error) {
return jpeg.Decode(bytes.NewReader(data))
}
func decodePNG(data []byte) (image.Image, error) {
return png.Decode(bytes.NewReader(data))
}
func decodeGIF(data []byte) (image.Image, error) {
return gif.Decode(bytes.NewReader(data))
}
func decodeBMP(data []byte) (image.Image, error) {
return bmp.Decode(bytes.NewReader(data))
}
func decodeTIFF(data []byte) (image.Image, error) {
return tiff.Decode(bytes.NewReader(data))
}
func decodeWebP(data []byte) (image.Image, error) {
return webp.Decode(bytes.NewReader(data))
}
// 编码函数实现
func encodeJPEG(filename string, img image.Image) error {
out, err := os.Create(filename)
if err != nil {
return err
}
defer out.Close()
return jpeg.Encode(out, img, &jpeg.Options{Quality: 85})
}
func encodePNG(filename string, img image.Image) error {
out, err := os.Create(filename)
if err != nil {
return err
}
defer out.Close()
return png.Encode(out, img)
}
func encodeGIF(filename string, img image.Image) error {
out, err := os.Create(filename)
if err != nil {
return err
}
defer out.Close()
return gif.Encode(out, img, &gif.Options{})
}
func encodeBMP(filename string, img image.Image) error {
out, err := os.Create(filename)
if err != nil {
return err
}
defer out.Close()
return bmp.Encode(out, img)
}
func encodeTIFF(filename string, img image.Image) error {
out, err := os.Create(filename)
if err != nil {
return err
}
defer out.Close()
return tiff.Encode(out, img, &tiff.Options{})
}
func encodeWebP(filename string, img image.Image) error {
out, err := os.Create(filename)
if err != nil {
return err
}
defer out.Close()
return webp.Encode(out, img, &webp.Options{Lossless: false, Quality: 80})
}
// 通用缩略图生成函数
func GenerateThumbnail(inputPath, outputPath string, width, height int) error {
// 读取原始图像数据
data, err := os.ReadFile(inputPath)
if err != nil {
return fmt.Errorf("读取文件失败: %v", err)
}
// 获取文件扩展名
ext := strings.ToLower(filepath.Ext(inputPath))
// 查找对应的解码器
decoder, ok := decoders[ext]
if !ok {
return fmt.Errorf("不支持的图像格式: %s", ext)
}
// 解码图像
img, err := decoder(data)
if err != nil {
return fmt.Errorf("解码失败: %v", err)
}
// 使用imaging生成缩略图
thumbnail := imaging.Thumbnail(img, width, height, imaging.Lanczos)
// 获取输出文件扩展名
outputExt := strings.ToLower(filepath.Ext(outputPath))
// 查找对应的编码器
encoder, ok := encoders[outputExt]
if !ok {
return fmt.Errorf("不支持的输出格式: %s", outputExt)
}
// 编码并保存缩略图
return encoder(outputPath, thumbnail)
}
func main() {
// 示例:为WebP文件生成缩略图
err := GenerateThumbnail(
"ml/input/waterski2.webp",
"ml/output/waterski2_thumb.webp",
400,
400,
)
if err != nil {
fmt.Printf("生成缩略图失败: %v\n", err)
return
}
fmt.Println("缩略图生成成功")
// 示例:为JPEG文件生成缩略图
err = GenerateThumbnail(
"ml/input/apple.jpg",
"ml/output/apple_thumb.jpg",
400,
400,
)
if err != nil {
fmt.Printf("生成缩略图失败: %v\n", err)
return
}
fmt.Println("JPEG缩略图生成成功")
}
这个实现通过以下方式解决WebP支持问题:
- 格式检测:基于文件扩展名自动选择正确的解码器
- 统一接口:为所有支持的格式提供一致的解码/编码接口
- WebP专门处理:使用
github.com/chai2010/webp包处理WebP格式 - 格式转换支持:支持不同格式之间的转换(如WebP转JPEG)
需要安装的依赖包:
go get github.com/disintegration/imaging
go get github.com/chai2010/webp
go get golang.org/x/image/bmp
go get golang.org/x/image/tiff
这个方案的优势:
- 支持所有常见图像格式(JPEG、PNG、GIF、BMP、TIFF、WebP)
- 保持原始代码的缩略图生成逻辑不变
- 提供统一的错误处理
- 支持格式转换
- 易于扩展新的图像格式

