zoukankan      html  css  js  c++  java
  • 异想家博客图片批量压缩程序

    为了方便给自己的博客配图,用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
    ", 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,改为了适合自己博客使用,源程序的代码更通用,更推荐在它基础上修改。

  • 相关阅读:
    服务器数据库不用开通远程连接通过工具在本地连接操作的方法
    怎么搜索同类网站
    Java三行代码搞定MD5加密,测试5c短信网关的demo
    iOS检测用户截屏并获取所截图片
    tomcat输出servlet-api.jar
    从svn资源库目录checkout出maven项目方法
    Maven打包pom里面配置exclude 排除掉环境相关的配置文件
    PHP获取毫秒时间戳,利用microtime()函数
    阿里云OneinStack,Linux下tomcat命令
    阿里云OneinStack数据库相关
  • 原文地址:https://www.cnblogs.com/sandeepin/p/jfz-blog-pic-compress.html
Copyright © 2011-2022 走看看