Posted on

Tinypng script

Using the service from https://tinypng.com makes it easy to mass-shrink your PNG images to more palatable sizes, and it comes with a neat 500 free use transcodes per month, and it’s quite cheap after that.

Here’s a little script to help you with the work a bit.

Prerequisites:
bash, jq and curl.

Save the file as “tinify” and do a chmod 755 tinify

Flags:
-k <key> = API key for tinypng.com – can be omitted if specified in the environment variable by export TINIFY_API ="<api_key>"
-f <file> = Filename to compress
-r = Replace the original file with the compressed file. If not specified, the output file will be named tiny-<filename>
-v = verbose output
-s = Show compression statistics (1 line per file)

#!/bin/env bash
# (C) EmberLabs / Chris Sprucefield 2023.
# License: CC BY.

key=''
file=''
r_flag=false
v_flag=false
s_flag=false
s_arg="-s"

if [ "${TINIFY_API}" != "" ]
then
    if [ "${v_flag}" == true ] ; then echo "Using API key from env." ; fi
    key="${TINIFY_API}"
fi

while getopts 'rk:f:vsh?' flag; do
case "${flag}" in
    r) r_flag=true ;;
    k) key="${OPTARG}" ;;
    f) file="${OPTARG}" ;;
    v) v_flag=true
       s_arg="" ;;
    s) s_flag=true ;;
    *)
        echo "<cmd> -? | -h This help text"
        echo " -r Replace the original file with tinified file."
        echo " -k <apikey> The API key for tinify (or from \$TINIFY_API environment variable if set)"
        echo " -f <filename> The filename to encode (and replace if -r is specified)"
        echo " -v Verbose output"
        echo " -s Show compression statistics"
        exit 1
        ;;
    esac
done

if [ "${v_flag}" == true ] ; then echo "Processing ${file}" ; fi
JSON="$(curl ${s_arg} --user "api:${key}" --data-binary "@${file}" -i https://api.tinify.com/shrink | tail -1)"
URL="$(echo "${JSON}" | jq '.output.url' | sed 's/\"//g')"
ISIZE="$(echo "${JSON}" | jq '.input.size')"
OSIZE="$(echo "${JSON}" | jq '.output.size')"
RATIO="$(echo "${JSON}" | jq '.output.ratio')"
W="$(echo "${JSON}" | jq '.output.width')"
H="$(echo "${JSON}" | jq '.output.height')"

if [ "${ISIZE}" == "${OSIZE}" ]
then
    if [ "${v_flag}" == true ] ; then echo "No compression on ${file} - skipped." ; fi
    exit 0
fi

if [ "${URL}" != "null" ]
then
    if [ "${v_flag}" == true ] ; then echo "Fetching ${URL}" ; fi
    curl ${s_arg} "${URL}" -o "tiny-${file}"

    if [ "${r_flag}" == true ]
    then
        if [ "${v_flag}" == true ] ; then echo "Replacing original file" ; fi
        mv -f "tiny-${file}" "${file}"
    fi
    if [ "${s_flag}" == true ]
    then
        printf "%-40s %5d x %-5d In: %8d Out: %8d Ratio: %2.5f\n" "${file}" "${W}" "${H}" "${ISIZE}" "${OSIZE}" "${RATIO}"
    fi
else
    echo "Invalid response. (incorrect API key?)"
    exit 1
fi