Skip to content

Instantly share code, notes, and snippets.

@Sobsz
Last active June 21, 2021 19:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Sobsz/2ef8cad165d50451467d7062136c8ed0 to your computer and use it in GitHub Desktop.
Save Sobsz/2ef8cad165d50451467d7062136c8ed0 to your computer and use it in GitHub Desktop.
# makes a gif (or png sequence) from input.png where all instances of #ff00ff are rainbowified
# gif (`png = False`) doesn't support semi-transparency and makes gradients look ugly
# you might need to run `pip install numpy pillow` in admin command prompt first
# i don't think this is copyrightable even but just in case: cc0 unlicense 0bsd wtfpl
import math
import numpy
from PIL import Image
framecount = 360
framedelay = 50 # (for gif) in milliseconds, can't be lower than 20 (= 50 fps) i think?
saturation = 0.8
value = 0.8 # basically brightness
png = False
# https://gist.github.com/mathebox/e0805f72e7db3269ec22
def hsv_to_rgb(h, s, v):
i = math.floor(h*6)
f = h*6 - i
p = v * (1-s)
q = v * (1-f*s)
t = v * (1-(1-f)*s)
r, g, b = [
(v, t, p),
(q, v, p),
(p, v, t),
(p, q, v),
(t, p, v),
(v, p, q),
][int(i%6)]
return r, g, b
frames = []
name = "input.png"
img = numpy.array(Image.open(name).convert("RGBA"))
red, green, blue, alpha = img[:,:,0], img[:,:,1], img[:,:,2], img[:,:,3]
mask = (red == 255) & (green == 0) & (blue == 255)
for i in range(framecount):
img2 = numpy.copy(img)
img2[:,:,:3][mask] = tuple((i * 255 for i in hsv_to_rgb(i / framecount, saturation, value)))
frames.append(Image.fromarray(img2))
if png:
for i in range(framecount):
frames[i].save(f"rainbow_{i}.png")
else:
frames[0].save("rainbow.gif", save_all=True, append_images=frames[1:], optimize=0, duration=framedelay, loop=0, transparency=255)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment