Last active
November 25, 2022 14:46
-
-
Save acorn1010/31cc595805dd4f795651f297b6bfb926 to your computer and use it in GitHub Desktop.
Foony Generate Images Script (credit keraion)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# Credit to keraion for huge readability improvements and parallelization. | |
set -e | |
# Creates webp / avif images for images that don't already exist and places them in the public folder | |
# This script can take a while to run | |
# Install deps | |
# sudo apt-get install -f webp ffmpeg | |
# MacOS deps | |
# brew install zopfli | |
# brew install ffmpeg | |
# brew install joedrago/repo/avifenc | |
# Ensure deps are executable | |
chmod +x ./avifenc | |
chmod +x ./zopflipng | |
chmod +x ./magick | |
# Path variables for conversion | |
DESIGN_IMG_PATH=design/images | |
ITEM_DESIGN_IMG_PATH=${DESIGN_IMG_PATH}/items | |
CURSOR_DESIGN_IMG_PATH=${DESIGN_IMG_PATH}/games/account/items/Cursors | |
GAME_DESIGN_IMG_PATH=${DESIGN_IMG_PATH}/games | |
SITE_DESIGN_IMG_PATH=${DESIGN_IMG_PATH}/site | |
PUB_IMG_PATH=client/public/img | |
ITEM_PUB_IMG_PATH=${PUB_IMG_PATH}/items | |
CURSOR_PUB_IMG_PATH=${PUB_IMG_PATH}/games/account/items/Cursors | |
GAME_PUB_IMG_PATH=${PUB_IMG_PATH}/games | |
SITE_PUB_IMG_PATH=${PUB_IMG_PATH} | |
POST_PUB_IMG_PATH=${PUB_IMG_PATH}/posts | |
# Increase degree of parallelism | |
NUM_PROCESSES=8 | |
# Convert PNG to WEBP and AVIF. | |
function convert_images() { | |
input_file=${1?} | |
design_path=${2?} | |
pub_path=${3?} | |
image_type=${4?} # icon, cursor, other | |
if [ "${image_type}" == 'icon' ]; then | |
img_basename=$(sed -E "s#${design_path}/(.*)\.png#\1#" <<< ${input_file}) | |
else | |
img_basename=$(sed -E "s#${design_path}/(.*)\..{3}#\1#" <<< ${input_file}) | |
fi | |
png_path=${pub_path}/${img_basename}.png | |
png_path_2x=${pub_path}/${img_basename}.2x.png | |
webp_path=${pub_path}/${img_basename}.webp | |
avif_path=${pub_path}/${img_basename}.avif | |
unset png_source_path[@] | |
unset magick_options[@] | |
case "${image_type}" in | |
'icon') | |
png_source_path[0]=${png_path_2x} | |
png_source_path[1]=${png_path} | |
magick_options[0]="-resize 300x300> -gravity center -trim" | |
magick_options[1]="-resize 150x150> -gravity center -trim" | |
avifenc_options="--min 23 --max 53 --minalpha 23 --maxalpha 53" | |
;; | |
'cursor') | |
png_source_path[0]=${png_path} | |
magick_options[0]="-resize 40x40>" | |
avifenc_options="--min 14 --max 21 --minalpha 14 --maxalpha 21" | |
;; | |
*) | |
png_source_path[0]=${png_path} | |
avifenc_options="--min 14 --max 21 --minalpha 14 --maxalpha 21" | |
;; | |
esac | |
# Create paths if it does not exist. | |
mkdir -p "$(dirname "${png_source_path[0]}")" | |
# Move file if necessary. | |
if [ ! -f "${png_source_path[0]}" ]; then | |
index=0 | |
for i in "${png_source_path[@]}"; do | |
./magick convert "${input_file}" -profile ./design/color_profiles/sRGBz.icc ${magick_options[index]} "${png_source_path[index]}" | |
./zopflipng -y --keepchunks=iCCP --lossy_transparent "${png_source_path[index]}" "${png_source_path[index]}" | |
index=$((index+1)) | |
done | |
fi | |
# Convert to WEBP if necssary. | |
if [ ! -f "${webp_path}" ]; then | |
cwebp -metadata icc -quiet -q 90 "${png_source_path[0]}" -o "${webp_path}" | |
fi | |
# Convert to AVIF if necessary. | |
if [ ! -f "${avif_path}" ]; then | |
# Firefox messes up on depth 10. If we use a limited range and depth 8, then we get the correct | |
# sRGB rednering. | |
./avifenc -c aom --speed 0 --jobs 12 --range limited --ignore-icc --yuv 444 ${avifenc_options} "${png_source_path[0]}" "${avif_path}" | |
fi | |
} | |
# export to access in bash subshell | |
export -f convert_images | |
# Convert GIF to WEBM. | |
function convert_gifs() { | |
input_file=${1?} | |
pub_path=${2?} | |
img_basename=$(sed -E "s#${pub_path}/(.*)\..{3}#\1#" <<< ${input_file}) | |
full_path=${pub_path}/${img_basename} | |
# Create paths if it does not exist. | |
mkdir -p "$(dirname "${full_path}")" | |
# Move file if necessary. | |
if [ ! -f "${full_path}.webm" ]; then | |
ffmpeg -y -i "${full_path}.gif" -c vp9 -b:v 0 -crf 40 "${full_path}.webm" | |
fi | |
} | |
# export to access in bash subshell | |
export -f convert_gifs | |
# These functions can run in parallel using xargs "-P #" value | |
find "${ITEM_DESIGN_IMG_PATH}" -type f -and -iname "*.png" -print0 | xargs -0 -P ${NUM_PROCESSES} -I {} bash -c 'convert_images "$@"' _ {} "${ITEM_DESIGN_IMG_PATH}" "${ITEM_PUB_IMG_PATH}" icon | |
find "${CURSOR_DESIGN_IMG_PATH}" -type f -and \( -iname "*.png" -o -iname "*.jpg" \) -print0 | xargs -0 -P ${NUM_PROCESSES} -I {} bash -c 'convert_images "$@"' _ {} "${CURSOR_DESIGN_IMG_PATH}" "${CURSOR_PUB_IMG_PATH}" cursor | |
find "${GAME_DESIGN_IMG_PATH}" -type f -and \( -iname "*.png" -o -iname "*.jpg" \) -print0 | xargs -0 -P ${NUM_PROCESSES} -I {} bash -c 'convert_images "$@"' _ {} "${GAME_DESIGN_IMG_PATH}" "${GAME_PUB_IMG_PATH}" other | |
find "${SITE_DESIGN_IMG_PATH}" -type f -and \( -iname "*.png" -o -iname "*.jpg" \) -print0 | xargs -0 -P ${NUM_PROCESSES} -I {} bash -c 'convert_images "$@"' _ {} "${SITE_DESIGN_IMG_PATH}" "${SITE_PUB_IMG_PATH}" other | |
find ${POST_PUB_IMG_PATH} -type f -and -iname "*.gif" -print0 | xargs -0 -P ${NUM_PROCESSES} -I {} bash -c 'convert_gifs "$@"' _ {} ${POST_PUB_IMG_PATH} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment