命令行压缩图片

作者: 左蓝 | 来源:发表于2017-02-22 23:43 被阅读375次

    Linux 下我常用的两个图片压缩工具就是:optipng 和 jpegoptim。
    但是今天在谷歌网页加载测评中,这两个工具表现不佳。于是使用在线工具来压缩。

    网址:https://tinypng.com
    还有个姐妹站,自己百度,压缩 JPG 格式的图片。这里以 PNG 格式为例。

    申请 API 直接点导航栏那里的开发者,输入邮箱名称即可。

    API 申请

    收到 API_KEY 之后可以使用 curl 来测试。

    curl --user api:YOUR_API_KEY \
         --data-binary @unoptimized.png -i https://api.tinify.com/shrink
    

    使用次数有限制,每个月500张。当然你可以换个邮箱申请什么的,一般来说个人用也不会超过500张的数量。


    使用次数与收费

    只是 curl 还是挺麻烦的,所以写成脚本来处理吧。
    首先新建一个文件,名为 api.key,然后里面填写收到的 API_KEY。
    新建脚本,内容如下,放在同一个目录中。

    #!/usr/bin/bash
    # 使用 TinyPNG 压缩图片
    
    API_KEY=`cat "$(dirname $0)"/api.key`
    API_URL=https://api.tinify.com/shrink
    
    # 压缩后的文件保存在这里
    output_dir=
    # 要压缩的文件
    files=()
    
    show_help() {
      echo -e \
    "使用 TinyPNG 压缩图片的脚本,默认覆盖原文件。支持 png 和 jpg 格式。
    Usage: $0 [option] [file/directory]...
    选项:
        -o [输出目录]      指定压缩后的文件保存目录,默认覆盖原文件。
        -h, --help           显示帮助信息。
    }
    
    # 检查输出目录是否存在,并尝试创建文件夹。
    parse_output_dir() {
      if [[ "$1" = '-o' ]]; then
        # 确保以 '/' 结尾
        output_dir=${2%/}/
        if [[ -e "$output_dir" ]]; then
          if [[ ! -d "$output_dir" ]]; then
            echo "Error: $output_dir 不是一个目录。"
            exit 1
          elif [[ ! -w "$output_dir" ]]; then
            echo "Error: $output_dir 目录不可写"
            exit 1
          fi
        else
          mkdir "$output_dir" || exit 1
        fi
      fi
    }
    
    # 索引文件和目录,放进数组中等待处理。如果文件或者目录不存在则退出。
    parse_files() {
      start=0
      if [[ -n "$output_dir" ]]; then
        start=2
      fi
    
      args=("$@")
      for (( i = $start; i <= $#; i++ )); do
        path=${args[$i]}
        if [[ -f "$path" ]]; then
          files+=($path)
        elif [[ -d "$path" ]]; then
          for file in "`find \"$path\" -type f -regex '.*\.\(png\|jpg\)'`"; do
            if [[ -n "$file" ]]; then
              files+=("$file")
            fi
          done
        fi
      done
    }
    
    # 逐一处理图片
    minify_image() {
      local file=$1
      local response=`curl $API_URL -s --user api:$API_KEY --data-binary @"$file"`
      if [[ "$response" = *"\"error\""* ]]; then
        message=`echo "$response" | sed 's#.*"message":"\([^"]*\)".*#\1#'`
        if [[ -n "$message" ]]; then
          echo "$file: $message"
        else
          echo "$file: $response"
        fi
      else
        local url=`echo "$response" | sed 's#.*"url":"\([^"]*\)".*#\1#'`
        if [[ -n "$output_dir" ]]; then
          local output_path="$output_dir$file"
          local dir=`dirname $output_path`
          if [[ ! -d "$dir" ]]; then
            mkdir -p "$dir"
          fi
        else
          local output_path=$file
        fi
        curl $url -sSo "$output_path" --user api:$API_KEY
        if [[ "$?" = "0" ]]; then
          echo "$file: 压缩成功"
        else
          echo "$file: 下载失败"
        fi
      fi
    }
    
    if [[ "$#" = "0" || "$1" = "--help" || "$1" = "-h" ]]; then
      show_help
      exit
    elif [[ -e "$API_KEY" ]]; then
      echo "请保证 api.key 位置与内容正。"
    fi
    
    parse_output_dir $@
    parse_files $@
    
    export API_KEY
    export API_URL
    export output_dir
    export -f minify_image
    
    if [[ "${#files[@]}" -lt "1" ]]; then
      echo "没有文件需要压缩"
    else
      echo ${files[@]} | xargs -r -n1 -P10 bash -c 'minify_image "$@"' _{}
    fi
    

    源代码来自:
    https://github.com/bianjp/image-minifier/blob/master/minify.sh

    相关文章

      网友评论

        本文标题:命令行压缩图片

        本文链接:https://www.haomeiwen.com/subject/lkrvwttx.html