Skip to content

Instantly share code, notes, and snippets.

@Winterhuman
Last active September 18, 2023 16:36
Show Gist options
  • Save Winterhuman/c03a892f131c17f2ace4a1c42e9de06f to your computer and use it in GitHub Desktop.
Save Winterhuman/c03a892f131c17f2ace4a1c42e9de06f to your computer and use it in GitHub Desktop.
A script which finds the minimum PNG dimensions for a given aspect ratio and pixel count, creates a colour-cycling PPM file, and then converts it to PNG.
#!/bin/sh
# Licensed under the Zero-Clause BSD terms: https://opensource.org/license/0bsd
# Requires imagemagick, and optionally pngquant & optipng
#
# Argument 1: Number of pixels to fill, required.
# Argument 2: Height ratio, default 23.
# Argument 3: Width ratio, default 5.
pquit() { printf "\033[1m\033[31m%b\033[0;39m" "$1"; exit 1; }
clean() { if ! rm -r "$tmp"; then pquit "Failed to delete $tmp!\n"; fi }
trap clean EXIT
tmp="$(mktemp -d)"
ppm="${tmp}/image.ppm"
image="header-pixel.png"
fill="${1:-"Not given"}"
hratio="${2:-23}"
wratio="${3:-5}"
if ! printf "%d" "$hratio" "$wratio" > /dev/null 2>&1 || [ "$hratio" -le 0 ] || [ "$wratio" -le 0 ]; then
pquit "Aspect ratio values must be positive integers!\n"; fi
if ! printf "%d" "$fill" > /dev/null 2>&1 || [ "$fill" -lt 0 ]; then
pquit "Fill value must be a positive integer!\n"; fi
if [ -e "$ppm" ]; then pquit "$ppm already exists!\n"; fi
# Finds the squareroot of '(H-ratio * Fill) / W-ratio', which is guaranteed to give
# a height which doesn't go over what's needed (but sometimes undershoots by 1).
input="$(( ("$wratio" * "$fill") / "$hratio" ))"
root="0"
iterate="$(( "$input" + 1 ))"
while [ "$root" -ne "$(( "$iterate" - 1 ))" ]; do
step="$(( ("$root" + "$iterate") / 2 ))"
if [ "$(( "$step" * "$step" ))" -le "$input" ]; then root="$step"
else iterate="$step"
fi
done
height="$root"
calcwidth () {
printf "%s" "$(( ("$1" * "$hratio") / "$wratio" ))"
}
width="$(calcwidth "$height")"
# This is still necessary sometimes, try 40 and it'll say there's "-1 left" otherwise
while [ "$(( "$height" * "$width" ))" -le "$fill" ]; do
height="$(( "$height" + 1 ))"
width="$(calcwidth "$height")"
done
width="$(calcwidth "$height")"
left="$(( ("$height" * "$width") - "$fill" ))"
pstat() { printf "\033[1m\033[34m%s\033[0;39m\033[1m%b\033[0;39m\n" "$1" "$2"; }
pstat "Image path: " "$image"
pstat "Image dimensions: " "$width x $height"
pstat "Pixel fill: " "${fill}px (${left}px left)"
printf "P3\n%s %s\n255\n" "$width" "$height" > "$ppm"
#accent1="0 255 170\n0 223 148\n0 191 127\n0 159 106\n0 127 85\n0 96 64\n0 64 42"
accent1="0 255 170\n0 223 148\n0 191 127\n0 159 106\n0 127 85\n0 96 64"
#accent2="255 187 0\n223 164 0\n191 140 0\n159 117 0\n127 93 0\n96 70 0\n64 47 0"
accent2="255 187 0\n223 164 0\n191 140 0\n159 117 0\n127 93 0\n96 70 0"
#accent3="255 76 136\n223 66 119\n191 57 102\n159 48 85\n127 38 68\n96 29 51\n64 19 34"
accent3="255 76 136\n223 66 119\n191 57 102\n159 48 85\n127 38 68\n96 29 51"
runx() {
runx_index="$1"
while [ "$runx_index" -gt 0 ]; do
"$2" &
runx_index="$(( "$runx_index" - 1 ))"
done
}
shuffle() {
printf "%b" "$1" | shuf -n 1
}
three_col() {
printf "%b\n%b\n%b\n" "$(shuffle "$accent1")" "$(shuffle "$accent2")" "$(shuffle "$accent3")"
}
group="$(( "$fill" / 3 ))"
remain="$(( "$fill" % 3 ))"
runx "$group" three_col >> "$ppm"
wait
if [ "$remain" -eq 2 ]; then
printf "%b\n%b\n" "$(shuffle "$accent1")" "$(shuffle "$accent2")" >> "$ppm"
elif [ "$remain" -eq 1 ]; then
shuffle "$accent1" >> "$ppm"
fi
printf "%${left}s" ' ' | sed "s/ /0 0 0\n/g" >> "$ppm"
if ! convert -transparent "#000" "$ppm" "$image"; then
pquit "Failed to create $image!\n"; fi
oldsize="$(wc -c < "$image")"
if ! pngquant --quality 100-100 --speed 1 --strip "$image" --skip-if-larger --force --ext ".png"; then
printf "\033[1m\033[31m'pngquant' failed! Likely due to suboptimal output, such as:\033[0;39m\n"
printf "\033[1m\033[31m\tThe input image having more than 256 colours.\n\tThe output was larger than the input.\n\033[0;39m"
printf "\033[1mTrying 'optipng'...\033[0;39m\n"
fi
if ! optipng -quiet -o7 -strip all "$image"; then
pquit "'optipng' failed!\n"; fi
size="$(wc -c < "$image")"
pstat "Optimised size: " "$oldsize bytes -> $size bytes"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment