Pngcrush Script

I wrote this little bash script to pngcruns images in a directory. It will create one thread per processor.

#!/bin/bash
#multithreaded pngcrush
usage () {
echo "Usage: sudo $0 /dir"
exit 1
}
hash_progress () {
while [ -d /proc/$! ]; do echo -n "#"; sleep 1; done; echo -ne "\n"
}
# Check permissions for ownership fix after crush. Run with sudo.
if [ `id -un` != root ]; then
usage
fi
# Few sanity checks.
[ ! `which pngcrush` ] && echo "pngcrush missing" && exit 1
[ ! "$1" ] && usage
[ ! $# = 1 ] && usage
[ ! -d "$1" ] && usage
# Run 1 threads per core. Tested with 2 threads per core but found 1 or less better.
THREADS="$(grep -c processor /proc/cpuinfo)"
# Script start time
res1=$(date +%s.%N)
echo "Starting pngcrush of $1 with $THREADS threads"
# Get start bytes
STARTSIZE=$(du -bs $1|awk '{print $1}')
# Do stuff
find $1 -name \*.png -print0 |xargs -0 -n 1 -P $THREADS sh -c 'UOWNER=$(stat -c %U $0) && GOWNER=$(stat -c %G $0) && FILEPERMS=$(stat -c %a $0) && pngcrush -q -brute $0 temp.$$ >> /dev/null 2>&1 && mv temp.$$ $0 && chown $UOWNER:$GOWNER $0 && chmod $FILEPERMS $0' &
hash_progress
# Get end bytes
ENDSIZE=$(du -bs $1|awk '{print $1}')
if [ "$ENDSIZE" = "$STARTSIZE" ]; then
BYTESAVED="0"
else
BYTESAVED="$(echo "$STARTSIZE - $ENDSIZE"|bc)"
fi
# Stop time
res2=$(date +%s.%N)
# Output the savings
echo "Crushed $1 in $(echo "$res2 - $res1"|bc )sec saving $BYTESAVED Bytes"

Leave a Reply

Your email address will not be published. Required fields are marked *

*


*