实用工具png、jpg图片批量压缩bash脚本

平时写markdown笔记,通常会有一些截图在里边,原始图片很大,很占用空间,有必要给它们瘦身一下,注意了是尽可能无损瘦身,即分辨率不变,最大程度保留清晰度,同时减少文件大小。Linux里边提供了很多现成的工具,

在Linux命令行中,有几种方法可以压缩图片。下面是5种常用的方法:

1. 使用ImageMagick:ImageMagick是一个功能强大的命令行工具,可以处理图片。要压缩图片,首先需要安装ImageMagick。在安装完成后,可以运行以下命令来压缩图片:
“`bash
convert input.jpg -quality 80 output.jpg
“`
这个命令将把input.jpg图片压缩为80%的质量,并将压缩后的图片保存为output.jpg。

2. 使用OptiPNG:OptiPNG是一个专门用来压缩PNG格式图片的工具。要使用OptiPNG,需要先安装该工具,然后可以运行以下命令来压缩PNG图片:
“`bash
optipng -o7 input.png
“`
这个命令将使用最高级别的优化来压缩input.png图片。

3. 使用JPEGoptim:JPEGoptim是一个用于压缩JPEG格式图片的工具。要使用JPEGoptim,需要先安装该工具,然后可以运行以下命令来压缩JPEG图片:
“`bash
jpegoptim –max=80 input.jpg
“`
这个命令将把input.jpg图片的质量压缩到最大80%。

4. 使用Guetzli:Guetzli是一个Google开发的用于压缩JPEG图片的工具,它可以在保持可接受质量的前提下更进一步地减小图片文件的大小。要使用Guetzli,需要先下载并安装该工具,然后可以运行以下命令来压缩JPEG图片:
“`bash
guetzli –quality 85 input.jpg output.jpg
“`
这个命令将使用85%的质量压缩input.jpg图片,并将压缩后的图片保存为output.jpg。

5. 使用pngquant:pngquant是一个用于压缩PNG格式图片的工具,它采用了一种独特的无损压缩算法。要使用pngquant,需要先安装该工具,然后可以运行以下命令来压缩图片:
“`bash
pngquant –quality=65-80 input.png -o output.png
“`
这个命令将把input.png图片的质量压缩到65-80%之间,并将压缩后的图片保存为output.png。

这些方法提供了在Linux命令行中压缩图片的不同选项,您可以根据需要选择适合您的情况的方法。

经过使用,感觉jpegoptim、pngquant最给力,效果也不错,所以使用它们制作一个脚本来批量压缩图片,这样我们的markdown笔记就会占用空间小很多。

视频演示:【Shell脚本基础-练习04】批量压缩图片bash脚本_哔哩哔哩_bilibili

脚本:

=>  root @ 󰌽 redis1: 󰉋 ~/jiaoben-hub/04-image-compress-tool-------------------------------------------------- main (✓)
➜ cat image_compress_tool.sh
#!/bin/bash
#
#******************************************************************************************
#Author:                QianSong
#QQ:                    xxxxxxxxxx
#Date:                  2024-09-05
#FileName:              image_compress_tool.sh
#URL:                   https://github.com
#Description:           The test script
#Copyright (C):         QianSong 2024 All rights reserved
#******************************************************************************************

#######################################
# 打印使用方法
# Globals:
#   none
# Arguments:
#   none
# Outputs:
#   none
# Returns:
#   none
#######################################
function print_usage() {

    echo "用法:bash $0 [选项] [选项值]"
    echo ""
    echo "选项:"
    echo "  -s, --source-dir      源目录"
    echo "  -d, --dest-dir        目标目录"
    echo "  -t, --type            图片格式[png , jpg]"
    echo "  -h, --help            输出此帮助信息并退出"
}

#######################################
# 初始化全局变量
# Globals:
#   ${source_dir}、${dest_dir}、${image_type}
# Arguments:
#   none
# Outputs:
#   none
# Returns:
#   none
#######################################
function init_global_vars() {

    #work genarl var
    source_dir=""
    dest_dir=""
    image_type=""

    #color
    hei_color="\033[1;30m"
    hong_color="\033[1;31m"
    lv_color="\033[1;32m"
    huang_color="\033[1;33m"
    lan_color="\033[1;34m"
    zi_color="\033[1;35m"
    tianlan_color="\033[1;36m"
    bai_color="\033[1;37m"
    normal_color="\033[0m"
}

#######################################
# 获取用户传入的脚本参数,并作相应处理
# Globals:
#   ${source_dir}、${dest_dir}、${image_type}
# Arguments:
#   "$@"
# Outputs:
#   none
# Returns:
#   none
#######################################
function get_user_option_paramater() {

    if [ $# -eq 0 ]; then
        print_usage
        exit 0
    fi

    local opts
    opts="$(getopt -q -o s:,d:,t:,h -l source-dir:,dest-dir:,type:,help -- "$@")"
    if [ $? -ne 0 ]; then
        print_usage
        exit 1
    fi

    eval set -- "${opts}"
    while true; do
        case "$1" in
        -s | --source-dir)
            local regexp1="^\/"
            local danger_exp1="^\/+$"
            local trim_space1
            trim_space1="$(echo "$2" | awk '{gsub(/ /,"",$0); print $0}')"

            if [[ "$2" =~ ${regexp1} ]] && [[ ! "${trim_space1}" =~ ${danger_exp1} ]] && [ -d "$2" ]; then
                source_dir="$2"
            else
                echo -e "${hong_color}Bad option ${bai_color}$1 $2 ${zi_color}No such dir ${bai_color}$2 ${zi_color}Or dir can not be ${bai_color}\"/\"${normal_color}"
                exit 1
            fi
            shift 2
            ;;
        -d | --dest-dir)
            local regexp2="^\/"
            local danger_exp2="^\/+$"
            local trim_space2
            trim_space2="$(echo "$2" | awk '{gsub(/ /,"",$0); print $0}')"

            if [[ "$2" =~ ${regexp2} ]] && [[ ! "${trim_space2}" =~ ${danger_exp2} ]] && [ -d "$2" ]; then
                dest_dir="$2"
            else
                echo -e "${hong_color}Bad option ${bai_color}$1 $2 ${zi_color}No such dir ${bai_color}$2 ${zi_color}Or dir can not be ${bai_color}\"/\"${normal_color}"
                exit 1
            fi
            shift 2
            ;;
        -t | --type)
            local regexp3="^jpg$|^png$"
            if [[ "$2" =~ ${regexp3} ]]; then
                image_type="$2"
            else
                echo -e "${hong_color}Bad option ${bai_color}$1 $2 ${zi_color}Image type only one of png and jpg${normal_color}"
                exit 1
            fi
            shift 2
            ;;
        -h | --help)
            print_usage
            shift 1
            exit 0
            ;;
        --)
            shift 1
            break
            ;;
        *)
            echo -e "${hong_color}Internal error${normal_color}"
            exit 1
            ;;
        esac
    done
}

#######################################
# 图片压缩函数
# Globals:
#   none
# Arguments:
#   none
# Outputs:
#   none
# Returns:
#   none
#######################################
function convert_image() {

    check_valication_to_work

    local tools=(
        "pngquant"
        "jpegoptim"
    )

    if ! check_tools "${tools[@]}"; then
        echo -e "${hong_color}Error: ${bai_color}tools not install...${normal_color}"
        IFS=$' \t\n'
        local item
        for item in "${uninstall_tools[@]}"; do
            echo -e "${item}"
        done
        exit 2
    fi

    case "${image_type}" in
    "png")
        compress_image "png"
        ;;
    "jpg")
        compress_image "jpg"
        ;;
    *)
        echo -e "${hong_color}Internal error${normal_color}"
        exit 1
        ;;
    esac
}

#######################################
# 图片压缩
# Globals:
#   none
# Arguments:
#   $1: 传入图片格式png 、jpg
# Outputs:
#   none
# Returns:
#   none
#######################################
function compress_image() {

    local file_total

    if [ "$1" == "png" ]; then
        file_total="$(find "${source_dir}" -maxdepth 1 -name "*.png" | wc -l)"
    elif [ "$1" == "jpg" ]; then
        file_total="$(find "${source_dir}" -maxdepth 1 -name "*.jp*g" | wc -l)"
    fi

    if [ "${file_total}" -eq 0 ]; then
        echo -e "${hong_color}源目录不存在 ${bai_color}${1}${hong_color} 类型文件,无法继续...${normal_color}"
        exit 1
    fi

    #确保清空目标目录
    rm -rf "${dest_dir:?}"/* >/dev/null 2>&1

    local file_name item

    if [ "$1" == "png" ]; then
        while IFS= read -r -d '' item; do
            file_name="$(basename "${item}")"
            pngquant -v --force --quality 50-60 "${item}" -o "${dest_dir:?}/${file_name:?}"
        done < <(find "${source_dir}" -maxdepth 1 -name "*.png" -print0)
    elif [ "$1" == "jpg" ]; then
        while IFS= read -r -d '' item; do
            file_name="$(basename "${item}")"
            jpegoptim --max=50 --verbose -o --dest="${dest_dir:?}" "${item}"
        done < <(find "${source_dir}" -maxdepth 1 -name "*.jp*g" -print0)
    fi

    echo
    print_logo
    echo
    echo -e "${lv_color}压缩完成,前往 ${bai_color}${dest_dir}${lv_color} 查看...${normal_color}"
}

#######################################
# LOGO
# Globals:
#   none
# Arguments:
#   none
# Outputs:
#   none
# Returns:
#   none
#######################################
function print_logo() {

    echo -e "${zi_color}▜▘▞▀▖▙▗▌▞▀▖▛▀▘   ▞▀▖▞▀▖▙▗▌▛▀▖▛▀▖▛▀▘▞▀▖▞▀▖${normal_color}"
    echo -e "${zi_color}▐ ▙▄▌▌▘▌▌▄▖▙▄    ▌  ▌ ▌▌▘▌▙▄▘▙▄▘▙▄ ▚▄ ▚▄${normal_color}"
    echo -e "${zi_color}▐ ▌ ▌▌ ▌▌ ▌▌     ▌ ▖▌ ▌▌ ▌▌  ▌▚ ▌  ▖ ▌▖ ▌${normal_color}"
    echo -e "${zi_color}▀▘▘ ▘▘ ▘▝▀ ▀▀▘▀▀▀▝▀ ▝▀ ▘ ▘▘  ▘ ▘▀▀▘▝▀ ▝▀${normal_color}"
}

#######################################
# 检查必须得图片处理工具
# Globals:
#   ${uninstall_tools[@]}
# Arguments:
#   $1: 传入一个数组,包含工具集
# Outputs:
#   none
# Returns:
#   0: 表示工具集完整可以进行脚本
#   1: 表示缺少工具集不能继续脚本
#######################################
function check_tools() {

    uninstall_tools=()

    IFS=$' \t\n'
    local item
    for item in "$@"; do
        if type "${item}" >/dev/null 2>&1; then
            true
        else
            uninstall_tools+=("${item}")
        fi
    done

    if [ "${#uninstall_tools[@]}" -eq 0 ]; then
        return 0
    else
        return 1
    fi
}

#######################################
# 验证参数健全性,不全的参数将导致脚本退出
# Globals:
#   none
# Arguments:
#   none
# Outputs:
#   none
# Returns:
#   none
#######################################
function check_valication_to_work() {

    if [ -z "${source_dir}" ]; then
        echo -e "${hong_color}Error: ${bai_color}please define image source directory...${normal_color}"
        exit 1
    elif [ -z "${dest_dir}" ]; then
        echo -e "${hong_color}Error: ${bai_color}please define image dest directory...${normal_color}"
        exit 2
    elif [ -z "${image_type}" ]; then
        echo -e "${hong_color}Error: ${bai_color}please define image type png/jpg...${normal_color}"
        exit 3
    fi
}

#######################################
# 脚本的入口,程序执行的起点函数main
# Globals:
#   none
# Arguments:
#   "$@"
# Outputs:
#   none
# Returns:
#   none
#######################################
function main() {

    init_global_vars
    get_user_option_paramater "$@"
    convert_image
}

main "$@"

=>  root @ 󰌽 redis1: 󰉋 ~/jiaoben-hub/04-image-compress-tool-------------------------------------------------- main (✓)
➜

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值