#!/usr/bin/env zsh # Convert animated PNG to animated WebP. Maximum lossless compression no blend. setopt LOCAL_OPTIONS ERR_RETURN NO_UNSET PIPE_FAIL zmodload zsh/zutil local -a o_help=() local -a o_delay=() zparseopts -D -K -- h=o_help -help=o_help -delay:=o_delay if [[ ${#o_help} -ne 0 || ! -v 2 ]]; then local ret=$(( ${#o_help} ^ 1 )) print -u $(( 1 + ${ret} )) \ "usage: ${0} [-h|--help] [--delay MILLISECONDS]" \ " " return ${ret} fi local input=$(realpath ${1}) local output=$(realpath ${2}) autoload die for cmd in apngdis cwebp webpmux; do type ${cmd} >& - || die "ERROR: ${cmd} not found" done local tmpdir=$(mktemp --directory --suffix='.apng2webp') pushd ${tmpdir} mkdir -p apngdis pushd apngdis cp ${input} input.png apngdis input.png popd counter=1 for file in apngdis/apngframe*.png; do cwebp -lossless -q 100 ${file} -o $(printf "%03d.webp" ${counter}) counter=$(( counter+1 )) done local -a webpmux_options=() local -i counter=1 for file in apngdis/apngframe*.txt; do local delay=$(grep -Po '=\d+/\d+' ${file}) delay=${delay:1} delay=$(( ( 1000 + ${delay%/*} ) / ${delay#*/} )) [[ ${#o_delay} -eq 2 ]] && delay=${o_delay[2]} webpmux_options+=(-frame $(printf "%03d.webp" ${counter}) +${delay}+0+0+0-b) counter+=1 done # shellcheck disable=2086 webpmux ${webpmux_options} -o ${output} popd rm -r ${tmpdir}