GradientCode — wiki
Code follows, where "self.image" is a surface and "self.drawing_area" is a Rect showing the area to fill. "self.background_color" and "self.background_gradient" are two color tuples, eg. (0,255,255) for cyan.
x1 = self.drawing_area[0]
x2 = x1 + self.drawing_area[2]
a, b = self.background_color, self.background_gradient
y1 = self.drawing_area[1]
y2 = y1 + self.drawing_area[3]
h = y2-y1
rate = (float((b[0]-a[0])/h),
(float(b[1]-a[1])/h),
(float(b[2]-a[2])/h)
)
for line in range(y1,y2):
color = (min(max(a[0]+(rate[0]*line),0),255),
min(max(a[1]+(rate[1]*line),0),255),
min(max(a[2]+(rate[2]*line),0),255)
)
pygame.draw.line(self.image,color,(x1,line),(x2,line))
Original code reworked into a function, adding control of gradient direction, and making the rect optional.
def fill_gradient(surface, color, gradient, rect=None, vertical=True, forward=True):
"""fill a surface with a gradient pattern
Parameters:
color -> starting color
gradient -> final color
rect -> area to fill; default is surface's rect
vertical -> True=vertical; False=horizontal
forward -> True=forward; False=reverse
Pygame recipe: http://www.pygame.org/wiki/GradientCode
"""
if rect is None: rect = surface.get_rect()
x1,x2 = rect.left, rect.right
y1,y2 = rect.top, rect.bottom
if vertical: h = y2-y1
else: h = x2-x1
if forward: a, b = color, gradient
else: b, a = color, gradient
rate = (
float(b[0]-a[0])/h,
float(b[1]-a[1])/h,
float(b[2]-a[2])/h
)
fn_line = pygame.draw.line
if vertical:
for line in range(y1,y2):
color = (
min(max(a[0]+(rate[0]*(line-y1)),0),255),
min(max(a[1]+(rate[1]*(line-y1)),0),255),
min(max(a[2]+(rate[2]*(line-y1)),0),255)
)
fn_line(surface, color, (x1,line), (x2,line))
else:
for col in range(x1,x2):
color = (
min(max(a[0]+(rate[0]*(col-x1)),0),255),
min(max(a[1]+(rate[1]*(col-x1)),0),255),
min(max(a[2]+(rate[2]*(col-x1)),0),255)
)
fn_line(surface, color, (col,y1), (col,y2))