異想家博客圖片批量壓縮程序


為了方便給自己的博客配圖,用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,改為了適合自己博客使用,源程序的代碼更通用,更推薦在它基礎上修改。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM