Last active
September 18, 2023 16:36
-
-
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.
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
#!/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