重复使用OptiPNG/JPEGTran/GIFSicle
-
12-12-2019 - |
题
我没有足够的代表来评论贡献者的帖子,所以我会在这里提出这个问题。这里有一个关于批量图像优化的很好的问答 批量替换为压缩图像?
我想设置一个每月运行一次的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 (有一个