我没有足够的代表来评论贡献者的帖子,所以我会在这里提出这个问题。这里有一个关于批量图像优化的很好的问答 批量替换为压缩图像?

我想设置一个每月运行一次的cron,它执行上面链接中建议的图像优化。鉴于脚本的工作方式,它将尝试重新优化图像-但这些资源是否足够聪明,不会降低质量?

有帮助吗?

解决方案

图像压缩有两种选择,

  • 无损压缩
  • 有损压缩

前者可以在同一个文件上重复运行,而不会进一步降低质量(因为它唯一真正删除元数据)。显然,在第一次运行之后,后续运行没有任何好处。

后者不应该在同一个文件上重复运行,否则,您每次都会降低质量。防止这种情况发生的最简单方法是只保留一个已处理/未处理的活动日志。

我们为MageStack编写了几个脚本来执行此操作,一个是批处理/单数过程,另一个是"活动"过程(主动监视目录以进行更改并自行处理任何更改的文件)。

这是独立脚本 /microcloud/scripts/acc/image_optimise.sh,

#!/bin/bash

which sponge >/dev/null 2>&1 || ( echo "Error: moreutils must be installed" && exit 1 )
which advpng >/dev/null 2>&1 || ( echo "Error: advancecomp must be installed" && exit 1 )
which optipng >/dev/null 2>&1 || ( echo "Error: optipng must be installed" && exit 1 )
which jpegtran >/dev/null 2>&1 || ( echo "Error: libjpeg-progs must be installed" && exit 1 )
which jfifremove >/dev/null 2>&1 || ( echo "Error: jfifremove must be installed" && exit 1 )

function usage() {
  cat <<EOF
$(basename $0) Usage:

$(basename $0) [directory]

          directory      Directory containing images to optimise

EOF
  exit 0
}

function cleanup() {
  wait
  end_size=$(du -s . | awk '{print $1}')
  savings=$(( $start_size - $end_size ))
  megabytes=$(( $savings / 10**3 ))
  echo -e "\nSaved ${megabytes} MB"
  echo "Removing part files"
  find -path '*.optipart' -exec rm "{}" \; 2>/dev/null
  exit 1
}

function do_png () {
  advpng -z -q "$1"
  optipng -q "$1"
  return 0
}

function do_jpeg () {
  jpegtran -copy none -optimize -outfile "$1" "$1"
  jfifremove < "$1" | sponge "$1"
  return 0
}

function imgopt()
{
  ext=$(echo $1 | sed -E 's#.optipart$##g')
  case "$ext" in
    *.[Pp][Nn][Gg] )
      do_png "$1"
      ;;
    *.[Jj][Pp][Ee][Gg] )
      do_jpeg "$1"
      ;;
    *.[Jj][Pp][Gg] )
      do_jpeg "$1"
      ;;
    * )
    return 1
    ;;
  esac
}

trap cleanup 2 3

[ $# -lt 1 ] && usage
[ ! -d "$1" ] && echo "Error: Directory does not exist" && exit 1

dir=$1
cd $dir

touch .optimised.log
find . -regextype sed -regex '.*\.\(png\|jpe\?g\)$' | sed -E 's#\./##g' > .all.log
sort -u .all.log -o .all.log
sort -u .optimised.log -o .optimised.log
comm -23 .all.log .optimised.log > .process.log
rm .all.log

process_total=$(wc -l < .process.log)
total=0
count=0
files=()
start_time=$(date +%s)
threads=$(cat /proc/cpuinfo | grep -cE "^processor")
start_size=$(du -s . | awk '{print $1}')

echo "$process_total images to optimise"

while read i; do
  count=$(( count + 1 ))
  files+=( $i )
  if [ $count -eq $threads ] || [ $(( $process_total - $total )) -lt 1000 ]; then
    for f in ${files[@]}; do
      (
      cp -al $f{,.optipart}
      imgopt ${f}.optipart
      if [ $( stat -c %s ${f}.optipart ) -eq 0 ]; then
        rm ${f}.optipart
      else
        mv $f{.optipart,}
        echo $f >> .optimised.log
      fi
      ) &
    done
    wait
    total=$(( total + count ))
    count=0
    files=()
  else
    continue
  fi
  if [ $(( total % 1000 )) -eq 0 ]; then
    current_time=$(date +%s)
    elapsed=$(( $current_time - $start_time ))
    images_per_second=$(( $total / $elapsed ))
    remaining=$(( ( ( $process_total / $images_per_second ) - $elapsed ) / 60 ))
    percentage=$(( ( $total * 100 ) / $process_total ))
    completion_time=$( date +%r -d "$remaining minutes" )
    echo "$elapsed seconds elapsed. $total/$process_total images optimised (${percentage}%) at $images_per_second images/sec. Est. ~$remaining minutes remaining ($completion_time )"
  fi
done < .process.log

cleanup

另一个实用程序是 mage-watch.sh (来源太冗长,无法在这里发布),但您可以从 https://sys.sonassi.com/scripts/mage-watch.sh (有一个

许可以下: CC-BY-SA归因
scroll top