[Go]命令行工具-图片转webp

前言

功能:将jpg、png格式的图片转换成webp格式。使用的第三方库为github.com/kolesa-team/go-webp,另外这个库需要安装依赖libwebp

debian 13安装依赖

sudo apt install -y libwebp-dev

示例代码

package main

import (
	"flag"
	"fmt"
	"image/jpeg"
	"image/png"
	"log"
	"os"
	"path/filepath"
	"strings"

	"github.com/kolesa-team/go-webp/encoder"
	"github.com/kolesa-team/go-webp/webp"
)

var (
	flagInput   string
	flagQuality int = 80
	flagOutput  string
)

func getFileSize(file *os.File) int64 {
	fileInfo, err := file.Stat()
	if err != nil {
		panic(err)
	}
	return fileInfo.Size()
}

func jpgToWebp(srcFile *os.File, destFile *os.File) {

	img, err := jpeg.Decode(srcFile)
	if err != nil {
		panic(err)
	}

	options, err := encoder.NewLossyEncoderOptions(encoder.PresetDefault, float32(flagQuality))
	if err != nil {
		panic(err)
	}

	err = webp.Encode(destFile, img, options)
	if err != nil {
		panic(err)
	}

	// fmt.Printf("Converted %s to %s with quality %d\n", input, webpFileName, flagQuality)
	// fmt.Printf("Original size: %d bytes, WebP size: %d bytes\n", getFileSize(imgFile), getFileSize(webpFile))
}

func pngToWebp(srcFile *os.File, destFile *os.File) {
	img, err := png.Decode(srcFile)
	if err != nil {
		panic(err)
	}

	// 使用NewLossyEncoderOptions创建Options对象
	options, err := encoder.NewLossyEncoderOptions(encoder.PresetDefault, float32(flagQuality))
	if err != nil {
		panic(err)
	}

	err = webp.Encode(destFile, img, options)
	if err != nil {
		panic(err)
	}
}

func init() {
	flag.StringVar(&flagInput, "i", "", "required, input image file")
	flag.IntVar(&flagQuality, "q", 80, "optional, quality of webp file (0-100)")
	flag.StringVar(&flagOutput, "o", "", "optional, output webp file")
	flag.Parse()

	if flagQuality < 0 || flagQuality > 100 {
		log.Fatalf("quality must be between 0 and 100, got %d\n", flagQuality)
	}

	if flagInput == "" {
		log.Fatalln("input file is required")
	}

	if _, err := os.Stat(flagInput); os.IsNotExist(err) {
		log.Fatalf("input file does not exist: %s\n", flagInput)
	}

	if flagOutput == "" {
		flagOutput = strings.TrimSuffix(flagInput, filepath.Ext(flagInput)) + ".webp"
	}
}

func main() {
	srcFile, err := os.Open(flagInput)
	if err != nil {
		panic(err)
	}
	defer srcFile.Close()

	destFile, err := os.Create(flagOutput)
	if err != nil {
		panic(err)
	}
	defer destFile.Close()

	switch filepath.Ext(flagInput) {
	case ".jpg", ".jpeg":
		jpgToWebp(srcFile, destFile)
	case ".png":
		pngToWebp(srcFile, destFile)
	default:
		panic("input file must be jpg or png")
	}

	fmt.Printf("Converted %s to %s with quality %d\n", flagInput, flagOutput, flagQuality)
	fmt.Printf("Original size: %d bytes, WebP size: %d bytes\n", getFileSize(srcFile), getFileSize(destFile))
}

使用示例

$ ./towebp -i wallhaven-v99jqp_3840x2160.png
Converted wallhaven-v99jqp_3840x2160.png to wallhaven-v99jqp_3840x2160.webp with quality 80
Original size: 11910552 bytes, WebP size: 351326 bytes

Todo

posted @ 2025-09-07 18:20  花酒锄作田  阅读(30)  评论(0)    收藏  举报