ImageMagick with `-dither` and `-remap` could also work. For remap you would need an image with your desired palette, and IIRC you could use ImageMagick to produce that image but I cannot recall the incantation required for that.
This isn't the same though. With EventTarget, if one of the callback throws, the later callbacks would still get called. With yours the later callbacks don't get called.