Skip to content

Instantly share code, notes, and snippets.

@Winterhuman
Last active January 12, 2026 22:13
Show Gist options
  • Select an option

  • Save Winterhuman/c03a892f131c17f2ace4a1c42e9de06f to your computer and use it in GitHub Desktop.

Select an option

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.
#!/usr/bin/env -S unshare --mount --map-root-user /bin/sh
# Licensed under the Zero-Clause BSD terms: https://opensource.org/license/0bsd
# Requires: imagemagick & [sisyphus](https://gist.github.com/Winterhuman/21d7b148db40ff041f397b07a7aafb83)
#
# Argument 1: Number of pixels to fill, required
# Argument 2: Height ratio, default 23
# Argument 3: Width ratio, default 5
set -Ceuf
pstat() {
printf "%b\033[1m%b\033[0;39m" "${2:-\033[1m\033[34m::\033[0;39m }" "$1"
}
pquit() {
pstat "$1" "\033[1m\033[31m!!\033[0;39m "
exit 1
}
# Check if all arguments are valid
fill="${1:?"$(pquit "No arguments given!\n")"}"
if ! printf "%d" "$fill" >/dev/null 2>&1 || [ "$fill" -le 0 ]; then
pquit "'$fill' is not a positive integer!\n"; fi
pstat "Fill: $fill\n"
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
# Calculate the optimal/minimal image dimensions for the given fill value
calc_w() {
## '+ wratio - 1' yields a rounded up answer, instead of rounded down
printf "%d\n" "$(( (("$1" * hratio) + wratio - 1 ) / wratio ))"
}
calc_h() {
printf "%d\n" "$(( ( ("$1" * wratio) + hratio - 1 ) / hratio ))"
}
height="1"
width="$(calc_w "$height")"
bad="0"
## 'input + 1' is required to make this round up, since '$wratio' is in
## both the numerator and denominator (manual calculations verify this).
### '-1' is omitted from 'hratio + wratio' to handle '2:1' ratios
good="$((
( (fill + 1) * wratio + hratio + wratio ) /
(hratio + wratio)
))"
good="$(( "$(calc_h "$good")" + 2 ))"
if [ "$good" -gt 1 ]; then
while [ "$bad" -le "$(( good - 1 ))" ]; do
if [ "$(( width * height ))" -le "$fill" ]; then
bad="$(( height + 1 ))"
else
good="$height"
fi
height="$(( (bad + good) / 2 ))"
width="$(calc_w "$height")"
done
fi
height="$good"
width="$(calc_w "$height")"
blank="$(( (height * width) - fill ))"
groups="$(( fill / 3 ))"
remainofgroups="$(( fill % 3 ))"
pstat "Image dimensions: $width x $height\n"
pstat "Pixel fill: ${fill}px (${blank}px left)\n"
# Setup a private tmpfs for this script to use, which is what 'unshare' is for.
## 'nr_inodes' must be >= to 'max number of files + 1'
mount -t tmpfs -o nosuid,nodev,noexec,size=1G,nr_inodes=6 ppm2png /tmp/ ||
pquit "Failed to overmount '/tmp/'!\n"
# Create the PPM file.
## Create the blank lines.
### This method is faster than: `printf "%*s" "$blank" | sed "s/ /0 0 0\n/g"`
yes "0 0 0" | head --lines="$blank" >>/tmp/blank &
## Create the filled-in lines.
### `shuf` is the fastest method, followed by:
### `while :; do printf "%d\n" "$(( RANDOM % 7 ))"; done | head --lines="$groups"`.
### `while [ "$count" -gt 0 ]]; do ...; count="$(( count - 1 ))" done`.
#### The `yes` method would re-use the same '$RANDOM' value repeatedly
rand_fill() {
## `--head-count=` ignores numbers above the upper range value, aka. 6
shuf --input-range=0-6 --repeat | head --lines="$groups"
}
### Replace the colour indexes with their RGB values.
#### `[] ||` corrects for unclean divisions (e.g. 5 fill = 1 group + 2 remainder)
{
rand_fill
[ "$remainofgroups" -lt 1 ] || shuf --input-range=0-6 --head-count=1
} | sed -e "s/^0$/0 255 179/" \
-e "s/^1$/33 219 155/" \
-e "s/^2$/43 185 132/" \
-e "s/^3$/46 151 110/" \
-e "s/^4$/45 119 88/" \
-e "s/^5$/41 89 67/" \
-e "s/^6$/34 60 48/" >>/tmp/1 &
{
rand_fill
[ "$remainofgroups" -ne 2 ] || shuf --input-range=0-6 --head-count=1
} | sed -e "s/^0$/255 185 0/" \
-e "s/^1$/219 160 26/" \
-e "s/^2$/185 137 34/" \
-e "s/^3$/151 113 37/" \
-e "s/^4$/119 91 37/" \
-e "s/^5$/89 69 35/" \
-e "s/^6$/60 49 30/" >>/tmp/2 &
rand_fill | sed \
-e "s/^0$/255 47 120/" \
-e "s/^1$/220 48 105/" \
-e "s/^2$/186 48 91/" \
-e "s/^3$/153 46 77/" \
-e "s/^4$/122 42 64/" \
-e "s/^5$/91 37 50/" \
-e "s/^6$/62 31 38/" >>/tmp/3 &
wait
## Combine the PPM file parts
ppm="/tmp/img.ppm"
{
## This reads the HEAD heredoc
cat
## `head` removes any empty line(s) for when '$fill' isn't cleanly
## divisible by 3
paste --delimiters="\n" /tmp/1 /tmp/2 /tmp/3 | head --lines="$fill"
cat /tmp/blank
} <<-HEAD >"$ppm"
P3
$width $height
255
HEAD
## Save some space, just in case '$tmp_img' would bring it over the size limit
rm -- /tmp/1 /tmp/2 /tmp/3 /tmp/blank >/dev/null 2>&1 ||:
# Convert the PPM file to PNG
tmp_img="/tmp/tmp.png"
magick "$ppm" -transparent "#000" "$tmp_img" ||
pquit "Failed to create '$tmp_img'!\n"
# Move any existing output to a new '.old' path
mv_exist() {
[ -f "$1" ] || return 0
mv -- "$1" "$1.old"
}
mv_exist "header.png"
mv_exist "header.webp"
## Optimise PNG with 'sisyphus'
pstat "Optimising with Sisyphus...\n"
## '$tmp_img' exists outside Sisyphus's private tmpfs, meaning it can't see it.
## So, instead of copying '$tmp_img' somewhere, just give it a file descriptor
exec 3<"$tmp_img"
sisyphus --max-procs 24 --all-oxi true --results 16 /proc/self/fd/3 "header"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment