To digitally represent colors, one most often uses the RGB color system. By combining three fundamental light colors in certain ways, one can define a variety of different wavelengths of light. The human eye has three distinct photoreceptors for the aforementioned three colors, nearly all screens use pixels consisting of three parts in those colors and most image formats store the image data in the RGB color system.
However, there are other color systems than RGB with other strengths. Cycling through the colors of the rainbow, for example, is a lot easier using the HSL (or HSV) color model, as it is simply controlled by the hue.
Rainbowify uses the HSL color model to rainbowify a given image. To do so, the image is first converted into a grayscale image (averaging all three color channels). A pixel’s brightness is then interpreted as its hue with its saturation and lightness set to the maximum. As a final touch, the hue gets offset by a pixel-position dependent amount to create the overall appearance of a rainbow.
Source code is listed below and can also be downloaded.
# Jonathan Frech; 13th of August, 22nd of September 2017
# import from PIL import Image import sys, os # convert a given hsl color intor rgb # (function written on the 11th of July 2017) def hsl(h, s, l): # value range if not (0<=h<360 and 0<=s<=1 and 0<=l<=1): return c = (1-abs(2*l-1))*s hh = h/60. x = c*(1-abs(hh%2-1)) r = g = b = 0 if 0 <= hh < 1: r, g = c, x if 1 <= hh < 2: r, g = x, c if 2 <= hh < 3: g, b = c, x if 3 <= hh < 4: g, b = x, c if 4 <= hh < 5: r, b = x, c if 5 <= hh < 6: r, b = c, x m = l-c/2. return int((r+m)*255.), int((g+m)*255.), int((b+m)*255.) # main function def main(): # input length if len(sys.argv) < 2: print "Please specify an image."; return # image try: img = Image.open(sys.argv) except: print "Could not open image '%s'." % sys.argv; return w, h = img.size pix, j = img.load(), 0 # rainbowify image for y in range(h): for x in range(w): v = sum(pix[x, y])/3./255. pix[x, y] = hsl((v*360+j)%360, 1, .5) j += 1./w/h*360 # save image f, n = sys.argv.split("."), 1 F = ".".join(f[:-1]) + "_rainbowified." + f[-1] while os.path.exists(F): n += 1; F = ".".join(f[:-1]) + "_rainbowified%d." % n + f[-1] try: img.save(F) except: print "Could not save image as '%s'." % F print "Successfully saved image as '%s'." % F # run if main if __name__ == "__main__": main()