The transparent portraits came out of an external background-removal tool as RGBA PNGs. The hair, the shoulders, and the sweater all had soft anti-aliased edges. Anywhere the alpha had a smooth gradient from 255 to 0, WebP compression had to make a choice about how to encode that gradient.
The first attempt used Pillow’s default save options. The output looked fine on a white background and looked terrible on the aurora. The dark teal in the aurora made every compression artifact in the alpha channel visible as a faint hard outline around the head. From three feet away the photo looked like it had been cut out with scissors.
The fix was three parameters:
img.save(target, 'WEBP',
quality=92,
alpha_quality=100,
method=6,
exact=True)
quality=92 is for the color channels. The eye is forgiving there because most of the surface is skin and fabric.
alpha_quality=100 keeps the alpha channel uncompressed. The file gets a few KB heavier per frame, but the soft edges stay smooth. This is the one that matters.
method=6 is the slowest compression effort. It runs once on my machine during the ship script, so the cost is invisible. The file is around 10% smaller than method=4 for the same visual quality.
exact=True keeps the RGB values in fully-transparent pixels. Some encoders zero them out to save bits, which looks fine until you composite the image on a different background and a halo of leftover color appears around the edges.
The principle: color compression and alpha compression are different problems. Treat them with different defaults.