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.

Honey bee
Honey bee (original)

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.

Fruit (original)

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.

Sunflower (original)
Thistle (original)
# 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[1])
	except: print "Could not open image '%s'." % sys.argv[1]; 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[1].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()

One thought on “Rainbowify

  1. Pingback: Third Anniversary – J-Blog

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.