0

i have a list of RGB colors and need to draw gradient between them in python. Have you any suggestions how to make it usin PIL library?

EDIT: I get this:

def gradient(list_of_colors):
    width = 600
    height = 480
    img = Image.new("RGB", (width, height))
    draw = ImageDraw.Draw(img)

    for i in range(len(list_of_colors)):
        r1,g1,b1 = list_of_colors[i]
        for x in range(width/len(list_of_colors)):
            colour = (r1,g1,b1)
            draw.line((x+(width/len(list_of_colors)*i), 0, x+(width/len(list_of_colors)*i), height), fill=colour)

    img.show()

gradient([(30, 198, 244), (99, 200, 72),(120, 50, 80),(200, 90, 140)])

and it draw me this: http://img59.imageshack.us/img59/1852/3gba.png

I just need to make it gradient between those colors not stripes of colors. (something like this) http://www.kees-tm.nl/uploads/colorgradient.jpg

user3102697
  • 11
  • 1
  • 1
  • 2
  • See my answer to [_Python - Range values to pseudocolor_](http://stackoverflow.com/questions/10901085/python-range-values-to-pseudocolor/10907855#10907855). – martineau Dec 14 '13 at 17:29
  • Welcome to Stack Overflow. Your question is nearly there! For the community to better answer, please edit it to include *how the output of your code does not meet your expectations*, and what you have tried in the contex of `PIL`. For more information, please re-read http://stackoverflow.com/help/how-to-ask –  Dec 14 '13 at 17:40
  • See if this helps: https://stackoverflow.com/q/22607043/5987 – Mark Ransom May 19 '22 at 00:06
  • Does this answer your question? [How to create colour gradient in Python?](https://stackoverflow.com/questions/25668828/how-to-create-colour-gradient-in-python) – pjpscriv Oct 08 '22 at 01:25

2 Answers2

3

I think code like this will work, it uses Linear Interpolation to create the gradient.

list_of_colors = [(30, 198, 244), (99, 200, 72),(120, 50, 80),(200, 90, 140)]

no_steps = 100

def LerpColour(c1,c2,t):
    return (c1[0]+(c2[0]-c1[0])*t,c1[1]+(c2[1]-c1[1])*t,c1[2]+(c2[2]-c1[2])*t)

for i in range(len(list_of_colors)-2):
    for j in range(no_steps):
        colour = LerpColour(list_of_colors[i],list_of_colors[i+1],j/no_steps)

Obviously I don't know how you are drawing the gradient so I've left it open to you, do what you like with the colour variable to draw each step of the gradient within the for loop. :)

Also: I don't understand list generation so if anyone can improve the LerpColour function to use it please edit my post :)

EDIT - Generating a list that can easily be iterated over when drawing with PIL:

gradient = []
for i in range(len(list_of_colors)-2):
    for j in range(no_steps):
        gradient.append(LerpColour(list_of_colors[i],list_of_colors[i+1],j/no_steps))
olegsson
  • 113
  • 3
  • 6
JamJar00
  • 339
  • 4
  • 13
  • applied you idea but still no changes, i still get lines of color not gradient – user3102697 Dec 14 '13 at 22:04
  • Can you give a screenshot of what you have, and a mock up of what you want? That way I (and others) will have a better idea of what we're aiming at :) – JamJar00 Dec 16 '13 at 22:15
  • I get this [link](http://imageshack.us/a/img59/1852/3gba.png) and want something like this [link](http://img138.imageshack.us/img138/7903/89q3.png) for any colors i put into that list – user3102697 Dec 17 '13 at 10:04
0

I've built my own thing for my own needs after trying to find something that could compute gradients efficiently on multi-dimensional arrays so I hope you don't mind alpha processing :)

def colorscale( r:int,g:int,b:int,a:int, R:int,G:int,B:int,A:int, s:float ) -> tuple:
    S = 1.-s
    return round(r*S+R*s),round(g*S+G*s),round(b*S+B*s),round(a*S+A*s)

this takes the same approach as JamJar's LerpColour, but I did the scaling in a more simplistic way.

though it's probably not the most efficient due to round(), but I needed the accuracy...

that said, alternatively you can use scalar (0.0 - 1.0) colors (like I am), to get rid of round() entirely ;)

def colorscale( r:float,g:float,b:float,a:float, R:float,G:float,B:float,A:float, s:float ) -> tuple:
    S = 1.-s
    return r*S+R*s,g*S+G*s,b*S+B*s,a*S+A*s

anyways, I know it's a late response, but I hope this answer helps anyone who needs it.

Tcll
  • 7,140
  • 1
  • 20
  • 23