Mar
10
Color Palette in Python
I though this might be of use to somebody. It got some rough edges but is good enoughâ„¢ for my needs.
# -*- coding: utf-8 -*-
from colorsys import rgb_to_hls, hls_to_rgb
from PIL import Image
import struct
from cStringIO import StringIO
__author__ = 'Simon Pantzare'
class Color(object):
def __init__(self, r, g, b):
self.r = r
self.g = g
self.b = b
self.h, self.l, self.s = rgb_to_hls(r/255.0, g/255.0, b/255.0)
self.h *= 360
self.l *= 100
self.s *= 100
class RangeImage(object):
def __init__(
self,
start_rgb,
lightness_pc,
hue_dg,
dim=(200,50)
):
"""
lightness_pc
Range 0-50%.
hue_dg
Range 0-180 degrees.
"""
self.start_color = Color(*start_rgb)
self.lightness_pc = lightness_pc
self.hue_dg = hue_dg
self.width_px = dim[0]
self.height_px = dim[1]
def h_vector(self):
assert 0 <= self.hue_dg and self.hue_dg <= 180
start_h = self.start_color.h - self.hue_dg
if start_h < 0:
start_h = 360 + start_h
incr = float(self.hue_dg*2) / self.height_px
return [(start_h+i*incr)%(360+1) for i in range(0, self.height_px)]
def l_vector(self):
assert 0 <= self.lightness_pc and self.lightness_pc <= 50
minv = max(self.start_color.l - self.lightness_pc, 0)
incr = float(self.lightness_pc*2) / self.width_px
return [min(minv+i*incr,100) for i in range(0, self.width_px)]
def image(self):
arr = [[0] * self.width_px for _ in range(self.height_px)] # the outer list comprehension IS needed
hues = self.h_vector()
ls = self.l_vector()
sat = self.start_color.s / 100
for row_idx, row in enumerate(arr):
h = hues[row_idx] / 360.0
for col_idx, px in enumerate(row):
l = ls[col_idx] / 100.0
r,g,b = hls_to_rgb(h, l, sat)
arr[row_idx][col_idx] = struct.pack(
"BBBB",
int(r*255),
int(g*255),
int(b*255),
255
)
buf = StringIO()
[[buf.write(px) for px in row] for row in arr]
buf.seek(0)
im = Image.frombuffer(
"RGBA",
(self.width_px, self.height_px),
buf.read(),
"raw",
"RGBA",
0,
1
)
return im
Output for RangeImage((0, 255, 0), 50, 180, (200, 100)).image():
