欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

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

功能目標(biāo)

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

技術(shù)選型

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

第三方庫:

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

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

項目結(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ā)生錯誤:", 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.初始化項目并安裝依賴:

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

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

3.運行程序:

go run main.go

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

實踐要點與注意事項

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

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

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

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

相關(guān)文章

  • GO中的條件變量sync.Cond詳解

    GO中的條件變量sync.Cond詳解

    條件變量是基于互斥鎖的,它必須基于互斥鎖才能發(fā)揮作用,條件變量的初始化離不開互斥鎖,并且它的方法有點也是基于互斥鎖的,這篇文章主要介紹了GO的條件變量sync.Cond,需要的朋友可以參考下
    2023-01-01
  • 詳解Golang中日志庫glog的使用

    詳解Golang中日志庫glog的使用

    golang/glog?是?C++?版本?google/glog?的?Go?版本實現(xiàn),基本實現(xiàn)了原生?glog?的日志格式,下面大家就跟隨小編一起了解一下glog的具體使用吧
    2023-09-09
  • Go?語言?net/http?包使用之HTTP?服務(wù)器、客戶端與中間件詳解

    Go?語言?net/http?包使用之HTTP?服務(wù)器、客戶端與中間件詳解

    Go 語言標(biāo)準(zhǔn)庫中的net/http包十分的優(yōu)秀,提供了非常完善的 HTTP 客戶端與服務(wù)端的實現(xiàn),僅通過幾行代碼就可以搭建一個非常簡單的 HTTP 服務(wù)器,本文給大家介紹Go語言net/http包使用之HTTP服務(wù)器、客戶端與中間件的操作,感興趣的朋友一起看看吧
    2025-05-05
  • goland中使用leetcode插件實現(xiàn)

    goland中使用leetcode插件實現(xiàn)

    本文主要介紹了goland中使用leetcode插件實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • Go語言中的定時器原理與實戰(zhàn)應(yīng)用

    Go語言中的定時器原理與實戰(zhàn)應(yīng)用

    在Go語言中,Timer和Ticker是處理定時任務(wù)的重要工具,Timer用于一次性事件,而Ticker則用于周期性事件,本文詳細(xì)介紹了這兩種定時器的創(chuàng)建、使用和停止方法,并通過實際案例展示了它們在監(jiān)控日志、檢查系統(tǒng)狀態(tài)等方面的應(yīng)用
    2024-10-10
  • Golang?單元測試和基準(zhǔn)測試實例詳解

    Golang?單元測試和基準(zhǔn)測試實例詳解

    這篇文章主要為大家介紹了Golang?單元測試和基準(zhǔn)測試實例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • Golang關(guān)鍵字defer的用法詳解

    Golang關(guān)鍵字defer的用法詳解

    defer是Go里面的一個關(guān)鍵字,用在方法或函數(shù)前面,作為方法或函數(shù)的延遲調(diào)用。這篇文章主要為大家介紹了defer的簡單使用,需要的可以參考一下
    2023-05-05
  • Go gRPC環(huán)境安裝教程示例詳解

    Go gRPC環(huán)境安裝教程示例詳解

    這篇文章主要為大家介紹了Go gRPC環(huán)境安裝的教程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • 詳解如何使用Go的Viper來解析配置信息

    詳解如何使用Go的Viper來解析配置信息

    Viper庫為Golang語言開發(fā)者提供了對不同數(shù)據(jù)源和不同格式的配置文件的讀取,是Go項目讀取配置的神器,我們今天就來講講如何使用Viper來解析配置信息,文中通過代碼示例講解非常詳細(xì),需要的朋友可以參考下
    2024-01-01
  • golang拼接字符串的5種實現(xiàn)方式

    golang拼接字符串的5種實現(xiàn)方式

    文章總結(jié)了五種拼接字符串的方式,包括使用 "+"、strings.Join()、fmt.Sprint、bytes.Buffer 和 strings.Builder,每種方式都有其適用場景和性能特點
    2024-12-12

最新評論