異想家部落格圖片批量壓縮程式
阿新 • • 發佈:2020-02-01
為了方便給自己的部落格配圖,用Golang寫了一個指令碼處理,現分享出來,有需要的朋友也可以參考修改使用。
壓縮規則
1、圖片都等比例壓縮,不破壞長寬比。
2、如果是橫屏圖片,壓縮到寬度為1280,高度適應。
3、如果是豎屏圖片,壓縮到高度為1000,寬度適應。
4、如果解析度小於這個,不壓縮。
5、支援png、jpg、jpeg。
使用方法
go build jfzBlogPicCompress.go
原圖放在當前目錄下的raw目錄中,壓縮後的圖片生成在thumb目錄下,執行生成的二進位制檔案即可,壓縮完5s後程序退出。
原始碼
檔名jfzBlogPicCompress.go:
package main import ( "fmt" "github.com/nfnt/resize" "image" "image/jpeg" "image/png" "io" "log" "os" "path/filepath" "strings" "time" ) type InputArgs struct { OutputPath string /** 輸出目錄 */ LocalPath string /** 輸入的目錄或檔案路徑 */ Quality int /** 質量 */ Width int /** 寬度尺寸,畫素單位 */ Format string /** 格式 */ } var inputArgs InputArgs func main() { execute() fmt.Printf("處理完成,5秒後自動退出……") time.Sleep(5 * time.Second) /** 如果不是自己點選退出,延時5s */ } // 執行壓縮 func execute() { fmt.Println("開始批量壓縮...") inputArgs.LocalPath = "./raw/" inputArgs.OutputPath = "./thumb/" inputArgs.Quality = 90 inputArgs.Width = 1280 fmt.Println("壓縮規則:寬度1280,如果是豎圖,高度1000 壓縮質量:", inputArgs.Quality) GetFilelist(inputArgs.LocalPath) fmt.Println("圖片儲存在:" + inputArgs.OutputPath) } // 遍歷輸入原圖目錄的圖片 func GetFilelist(path string) { /** 建立輸出目錄 */ errC := os.MkdirAll(inputArgs.OutputPath, 0777) if errC != nil { fmt.Printf("%s", errC) return } err := filepath.Walk(path, func(pathFound string, f os.FileInfo, err error) error { if f == nil { return err } // 是否是目錄 if f.IsDir() { return nil } // 檔案是否是圖片 localPath, format, _ := isPictureFormat(pathFound) outputPath := strings.Replace(localPath, "raw", "thumb", 1) if localPath != "" { if !imageCompress( func() (io.Reader, error) { return os.Open(localPath) }, func() (*os.File, error) { return os.Open(localPath) }, outputPath, inputArgs.Quality, inputArgs.Width, format) { fmt.Println("生成縮圖失敗") } else { fmt.Println("生成縮圖成功 " + outputPath) } } return nil }) if err != nil { fmt.Printf("輸入的路徑資訊有誤 %v\n", err) } } // 壓縮演算法 func imageCompress( getReadSizeFile func() (io.Reader, error), getDecodeFile func() (*os.File, error), to string, Quality, base int, format string) bool { // 讀取檔案 file_origin, err := getDecodeFile() defer file_origin.Close() if err != nil { fmt.Println("os.Open(file)錯誤") log.Fatal(err) return false } var origin image.Image var config image.Config var temp io.Reader // 讀取尺寸 temp, err = getReadSizeFile() if err != nil { fmt.Println("os.Open(temp)") log.Fatal(err) return false } var typeImage int64 format = strings.ToLower(format) if format == "jpg" || format == "jpeg" { // jpg 格式 1 typeImage = 1 origin, err = jpeg.Decode(file_origin) if err != nil { fmt.Println("jpeg.Decode(file_origin)") log.Fatal(err) return false } temp, err = getReadSizeFile() if err != nil { fmt.Println("os.Open(temp)") log.Fatal(err) return false } config, err = jpeg.DecodeConfig(temp) if err != nil { fmt.Println("jpeg.DecodeConfig(temp)") return false } } else if format == "png" { // png 格式 0 typeImage = 0 origin, err = png.Decode(file_origin) if err != nil { fmt.Println("png.Decode(file_origin)") log.Fatal(err) return false } temp, err = getReadSizeFile() if err != nil { fmt.Println("os.Open(temp)") log.Fatal(err) return false } config, err = png.DecodeConfig(temp) if err != nil { fmt.Println("png.DecodeConfig(temp)") return false } } // 等比縮放(壓縮到1280的寬,如果圖片是豎著的,限定高最多1000) fixBase := base heightBase := fixBase * config.Height / config.Width if config.Height > config.Width { heightBase = 1000 fixBase = heightBase * config.Width / config.Height } // 基準 width := uint(fixBase) height := uint(heightBase) canvas := resize.Thumbnail(width, height, origin, resize.Lanczos3) file_out, err := os.Create(to) defer file_out.Close() if err != nil { log.Fatal(err) return false } if typeImage == 0 { err = png.Encode(file_out, canvas) if err != nil { fmt.Println("壓縮圖片失敗") return false } } else { err = jpeg.Encode(file_out, canvas, &jpeg.Options{Quality}) if err != nil { fmt.Println("壓縮圖片失敗") return false } } return true } // 是否是圖片 func isPictureFormat(path string) (string, string, string) { temp := strings.Split(path, ".") if len(temp) <= 1 { return "", "", "" } mapRule := make(map[string]int64) // 在這裡可以新增其他格式 mapRule["jpg"] = 1 mapRule["JPG"] = 1 mapRule["png"] = 1 mapRule["PNG"] = 1 mapRule["jpeg"] = 1 mapRule["JPEG"] = 1 if mapRule[temp[1]] == 1 { println(temp[1]) return path, temp[1], temp[0] } else { return "", "", "" } }
參考
程式碼參考了golang_image_compress,改為了適合自己部落格使用,源程式的程式碼更通用,更推薦在它基礎上修改