最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Go語言開發(fā)實(shí)現(xiàn)一個(gè)圖片批量壓縮工具

 更新時(shí)間:2025年09月11日 08:22:03   作者:程序員愛釣魚  
在日常開發(fā)和辦公中,圖片體積過大會(huì)帶來不少困擾,本文將使用Go語言編寫一個(gè)圖片批量壓縮工具,文中的示例代碼講解詳細(xì),需要的可以了解下

在日常開發(fā)和辦公中,圖片體積過大會(huì)帶來不少困擾:網(wǎng)頁加載慢、存儲(chǔ)占用大、郵件難以發(fā)送。很多時(shí)候,我們并不需要極致的畫質(zhì),而是需要在清晰度和體積之間找到平衡。今天我們就用 Go 寫一個(gè)圖片批量壓縮工具,從設(shè)計(jì)到實(shí)現(xiàn),完整走一遍。

功能目標(biāo)

  • 批量處理:支持整個(gè)目錄下的所有圖片文件(支持遞歸)。
  • 格式支持:JPEG、PNG、WebP。
  • 自定義壓縮質(zhì)量:用戶可以通過參數(shù)指定壓縮比。
  • 輸出目錄可選:壓縮后的圖片保存到指定文件夾,默認(rèn)生成 output。
  • 保留文件結(jié)構(gòu):輸出文件夾下的路徑結(jié)構(gòu)與原始一致。
  • 簡單易用:命令行參數(shù)運(yùn)行,不依賴復(fù)雜環(huán)境。

技術(shù)選型

標(biāo)準(zhǔn)庫:imageimage/jpeg、image/png

第三方庫:

github.com/chai2010/webp —— WebP 編解碼

Go 并發(fā):使用 goroutine + worker pool 來提升批量處理效率。

項(xiàng)目結(jié)構(gòu)(示意)

img-compressor/
├── main.go
├── go.mod

完整代碼(main.go)

package main

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

	"github.com/chai2010/webp"
)

type Options struct {
	InputDir   string
	OutputDir  string
	Quality    int
	Workers    int
	Recursive  bool
}

func main() {
	opts := Options{
		InputDir:  "./images",   // 輸入目錄
		OutputDir: "./output",   // 輸出目錄
		Quality:   75,           // 壓縮質(zhì)量(0-100)
		Workers:   4,            // 并發(fā) worker 數(shù)
		Recursive: true,         // 是否遞歸
	}

	if err := run(opts); err != nil {
		fmt.Println("? 發(fā)生錯(cuò)誤:", err)
		os.Exit(1)
	}
	fmt.Println("? 批量壓縮完成!")
}

func run(opts Options) error {
	// 收集所有待處理文件
	var files []string
	err := filepath.Walk(opts.InputDir, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		if info.IsDir() {
			if path != opts.InputDir && !opts.Recursive {
				return filepath.SkipDir
			}
			return nil
		}
		ext := strings.ToLower(filepath.Ext(info.Name()))
		if ext == ".jpg" || ext == ".jpeg" || ext == ".png" || ext == ".webp" {
			files = append(files, path)
		}
		return nil
	})
	if err != nil {
		return err
	}

	if len(files) == 0 {
		return fmt.Errorf("沒有找到任何圖片文件")
	}

	// worker pool
	fileCh := make(chan string)
	var wg sync.WaitGroup

	for i := 0; i < opts.Workers; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			for f := range fileCh {
				if err := compressImage(f, opts); err != nil {
					fmt.Printf("?? 壓縮失敗 %s: %v\n", f, err)
				} else {
					fmt.Printf("? 壓縮完成: %s\n", f)
				}
			}
		}()
	}

	for _, f := range files {
		fileCh <- f
	}
	close(fileCh)

	wg.Wait()
	return nil
}

// 壓縮單張圖片
func compressImage(path string, opts Options) error {
	inFile, err := os.Open(path)
	if err != nil {
		return err
	}
	defer inFile.Close()

	img, format, err := image.Decode(inFile)
	if err != nil {
		return fmt.Errorf("解碼失敗: %w", err)
	}

	// 輸出路徑
	rel, _ := filepath.Rel(opts.InputDir, path)
	outPath := filepath.Join(opts.OutputDir, rel)
	if err := os.MkdirAll(filepath.Dir(outPath), 0755); err != nil {
		return err
	}

	outFile, err := os.Create(outPath)
	if err != nil {
		return err
	}
	defer outFile.Close()

	switch format {
	case "jpeg":
		err = jpeg.Encode(outFile, img, &jpeg.Options{Quality: opts.Quality})
	case "png":
		encoder := png.Encoder{CompressionLevel: png.BestCompression}
		err = encoder.Encode(outFile, img)
	case "webp":
		err = webp.Encode(outFile, img, &webp.Options{Quality: float32(opts.Quality)})
	default:
		return fmt.Errorf("不支持的格式: %s", format)
	}
	return err
}

使用方法

1.初始化項(xiàng)目并安裝依賴:

go mod init img-compressor
go get github.com/chai2010/webp

2.放置圖片到 ./images 目錄。

3.運(yùn)行程序:

go run main.go

4.查看壓縮結(jié)果: 所有壓縮后的圖片會(huì)保存在 ./output 目錄下,目錄結(jié)構(gòu)保持不變。

實(shí)踐要點(diǎn)與注意事項(xiàng)

  • 質(zhì)量參數(shù):JPEG 和 WebP 可以用 0-100 來控制壓縮比;PNG 主要通過壓縮等級控制體積,但效果有限。
  • 批量優(yōu)化:若圖片數(shù)量很多,可以用 goroutine worker pool 提升效率,避免一次性開太多協(xié)程。
  • 格式兼容:WebP 在一些老舊系統(tǒng)和瀏覽器上兼容性不足,若是做網(wǎng)頁資源,需要配合 fallback。
  • 壓縮策略:有時(shí)候先統(tǒng)一縮放圖片(比如長邊 1080px),再壓縮比單純調(diào)整質(zhì)量更省空間。

進(jìn)一步擴(kuò)展

  • 添加 命令行參數(shù)(例如用 flagcobra),讓用戶可以指定輸入目錄、輸出目錄、質(zhì)量、遞歸開關(guān)等。
  • 支持 縮放功能(如最大寬高)。
  • 輸出 統(tǒng)計(jì)信息(壓縮前后大小對比,總共節(jié)省空間)。
  • 打包為跨平臺(tái)可執(zhí)行文件,方便非技術(shù)人員直接使用。

到此這篇關(guān)于Go語言開發(fā)實(shí)現(xiàn)一個(gè)圖片批量壓縮工具的文章就介紹到這了,更多相關(guān)Go圖片批量壓縮內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Golang遠(yuǎn)程調(diào)用框架RPC的具體使用

    Golang遠(yuǎn)程調(diào)用框架RPC的具體使用

    Remote Procedure Call (RPC) 是一種使用TCP協(xié)議從另一個(gè)系統(tǒng)調(diào)用應(yīng)用程序功能執(zhí)行的方法。Go有原生支持RPC服務(wù)器實(shí)現(xiàn),本文通過簡單實(shí)例介紹RPC的實(shí)現(xiàn)過程
    2022-12-12
  • 完美解決golang go get私有倉庫的問題

    完美解決golang go get私有倉庫的問題

    這篇文章主要介紹了完美解決golang go get私有倉庫的問題,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-05-05
  • 基于go實(shí)例網(wǎng)絡(luò)存儲(chǔ)協(xié)議詳解

    基于go實(shí)例網(wǎng)絡(luò)存儲(chǔ)協(xié)議詳解

    這篇文章主要為大家介紹了基于go實(shí)例網(wǎng)絡(luò)存儲(chǔ)協(xié)議詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • 深入理解Go語言unsafe包

    深入理解Go語言unsafe包

    Go語言通過類型和內(nèi)存安全設(shè)計(jì)保障可靠性,但unsafe包允許底層內(nèi)存操作以實(shí)現(xiàn)性能優(yōu)化與特殊交互,適用于結(jié)構(gòu)體字段訪問、零拷貝轉(zhuǎn)換等場景,感興趣的可以了解一下
    2025-08-08
  • 詳解Go語言中的監(jiān)視器模式與配置熱更新

    詳解Go語言中的監(jiān)視器模式與配置熱更新

    這篇文章主要為大家詳細(xì)介紹了Go語言中的監(jiān)視器模式與配置熱更新的相關(guān)知識,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-03-03
  • Go語言映射內(nèi)部實(shí)現(xiàn)及基礎(chǔ)功能實(shí)戰(zhàn)

    Go語言映射內(nèi)部實(shí)現(xiàn)及基礎(chǔ)功能實(shí)戰(zhàn)

    這篇文章主要為大家介紹了Go語言映射的內(nèi)部實(shí)現(xiàn)和基礎(chǔ)功能實(shí)戰(zhàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪<BR>
    2022-03-03
  • GoLang RabbitMQ TTL與死信隊(duì)列以及延遲隊(duì)列詳細(xì)講解

    GoLang RabbitMQ TTL與死信隊(duì)列以及延遲隊(duì)列詳細(xì)講解

    這篇文章主要介紹了GoLang RabbitMQ TTL與死信隊(duì)列以及延遲隊(duì)列,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2022-12-12
  • go語言LeetCode題解999可以被一步捕獲的棋子數(shù)

    go語言LeetCode題解999可以被一步捕獲的棋子數(shù)

    這篇文章主要為大家介紹了go語言LeetCode題解999可以被一步捕獲的棋子數(shù)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • Golang健康檢查接口的實(shí)現(xiàn)

    Golang健康檢查接口的實(shí)現(xiàn)

    本文主要介紹了Golang健康檢查接口的實(shí)現(xiàn),包括存活探針和就緒探針的區(qū)別,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2026-04-04
  • Go語言實(shí)現(xiàn)單端口轉(zhuǎn)發(fā)到多個(gè)端口

    Go語言實(shí)現(xiàn)單端口轉(zhuǎn)發(fā)到多個(gè)端口

    這篇文章主要為大家詳細(xì)介紹了Go語言實(shí)現(xiàn)單端口轉(zhuǎn)發(fā)到多個(gè)端口,文中的示例代碼講解詳細(xì),具有一定的參考價(jià)值,對大家的學(xué)習(xí)或工作有一定的幫助,需要的小伙伴可以了解下
    2024-02-02

最新評論

祁连县| 木里| 枝江市| 保靖县| 沙洋县| 佛冈县| 濮阳市| 德兴市| 濮阳市| 建昌县| 环江| 呼玛县| 锡林郭勒盟| 若尔盖县| 吉首市| 合阳县| 长垣县| 石楼县| 神农架林区| 广西| 襄垣县| 恩施市| 湘西| 徐州市| 佳木斯市| 邹城市| 台前县| 宜城市| 光泽县| 贺兰县| 祁连县| 开阳县| 明水县| 宁蒗| 迁安市| 辽源市| 永寿县| 揭阳市| 龙泉市| 垫江县| 乐东|