Skip to content

Instantly share code, notes, and snippets.

@szhu
Created April 6, 2025 21:43
Show Gist options
  • Save szhu/7e36f1b0d8f0064cfd593d728ae3e2a3 to your computer and use it in GitHub Desktop.
Save szhu/7e36f1b0d8f0064cfd593d728ae3e2a3 to your computer and use it in GitHub Desktop.
Make a basic macOS dynamic wallpaper
#!/bin/sh
# A script version of the instructions here: https://remove.codes/01-dynamic-wallpaper
set -e
# Helper functions.
verbose() {
echo >&2
echo $ "$@" >&2
"$@"
}
usage() {
echo "Usage: $0 <light_mode_image> <dark_mode_image> <output_image>"
echo "Creates a dynamic wallpaper from two images."
}
# Check that the args are valid, and calculate file paths.
SRC_LIGHT="$1"
SRC_DARK="$2"
OUT="$3"
if [ -z "$SRC_LIGHT" ] || [ -z "$SRC_DARK" ] || [ -z "$OUT" ]; then
usage
exit 1
fi
EXT="${SRC_LIGHT##*.}"
if [ "$EXT" != "${SRC_DARK##*.}" ]; then
echo "Error: The two images must have the same file extension."
exit 1
fi
DIR="make-dynamic-wallpaper.inprogress"
DST_LIGHT=$DIR/light-mode.$EXT
DST_LIGHT_XMP=$DIR/light-mode.xmp
DST_DARK=$DIR/dark-mode.$EXT
# Install dependencies.
brew list "libheif" "exiv2" >/dev/null || verbose brew install "libheif" "exiv2"
# Write and copy all necessary files.
verbose mkdir "$DIR"
verbose cp "$SRC_LIGHT" "$DST_LIGHT"
verbose cp "$SRC_DARK" "$DST_DARK"
verbose cat <<EOF >"$DST_LIGHT_XMP"
<?xpacket?>
<x:xmpmeta xmlns:x="adobe:ns:meta">
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns">
<rdf:Description xmlns:apple_desktop="http://ns.apple.com/namespace/1.0"
apple_desktop:apr=
"YnBsaXN0MDDSAQMCBFFsEAFRZBAACA0TEQ/REMOVE/8BAQAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAFQ=="/>
</rdf:RDF>
</x:xmpmeta>
EOF
# Do the conversions.
verbose exiv2 -i X in "$DST_LIGHT"
if [ "$(echo "$EXT" | tr '[:upper:]' '[:lower:]')" = "png" ]; then
verbose heif-enc -L "$DST_LIGHT" "$DST_DARK" -o "$OUT"
else
verbose heif-enc "$DST_LIGHT" "$DST_DARK" -o "$OUT"
fi
# Clean up.
verbose rm -rf "$DIR"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment