[PIL:生成垂直渐变图像

问题描述 投票:2回答:2

在Android中,我使用以下代码生成了我需要的渐变背景:

<gradient
    android:angle="90"
    android:startColor="#40000000"
    android:endColor="#00000000"
    android:type="linear" />

背景从上到下从浅变暗。我想知道如何在带有PIL的Python中执行相同的操作,因为我需要对另一个用Python编写的程序具有相同的效果。

python python-imaging-library gradient
2个回答
6
投票

这里显示了绘制多色矩形水平和垂直渐变的方法。

from PIL import Image, ImageDraw

BLACK, DARKGRAY, GRAY = ((0,0,0), (63,63,63), (127,127,127))
LIGHTGRAY, WHITE = ((191,191,191), (255,255,255))
BLUE, GREEN, RED = ((0, 0, 255), (0, 255, 0), (255, 0, 0))

class Point(object):
    def __init__(self, x, y):
        self.x, self.y = x, y

    @staticmethod
    def from_point(other):
        return Point(other.x, other.y)


class Rect(object):
    def __init__(self, x1, y1, x2, y2):
        minx, maxx = (x1,x2) if x1 < x2 else (x2,x1)
        miny, maxy = (y1,y2) if y1 < y2 else (y2,y1)
        self.min = Point(minx, miny)
        self.max = Point(maxx, maxy)

    @staticmethod
    def from_points(p1, p2):
        return Rect(p1.x, p1.y, p2.x, p2.y)

    def __str__(self):
        return 'Rect({:d}, {:d}, {:d}, {:d})'.format(self.min.x, self.min.y,
                                                     self.max.x, self.max.x)
    width  = property(lambda self: self.max.x - self.min.x)
    height = property(lambda self: self.max.y - self.min.y)


def gradient_color(minval, maxval, val, color_palette):
    """ Computes intermediate RGB color of a value in the range of minval
        to maxval (inclusive) based on a color_palette representing the range.
    """
    max_index = len(color_palette)-1
    delta = maxval - minval
    if delta == 0:
        delta = 1:
    v = float(val-minval) / delta * max_index
    i1, i2 = int(v), min(int(v)+1, max_index)
    (r1, g1, b1), (r2, g2, b2) = color_palette[i1], color_palette[i2]
    f = v - i1
    return int(r1 + f*(r2-r1)), int(g1 + f*(g2-g1)), int(b1 + f*(b2-b1))

def horz_gradient(draw, rect, color_func, color_palette):
    minval, maxval = 1, len(color_palette)
    delta = maxval - minval
    for x in range(rect.min.x, rect.max.x+1):
        f = (x - rect.min.x) / float(rect.width)
        val = minval + f * delta
        color = color_func(minval, maxval, val, color_palette)
        draw.line([(x, rect.min.y), (x, rect.max.y)], fill=color)

def vert_gradient(draw, rect, color_func, color_palette):
    minval, maxval = 1, len(color_palette)
    delta = maxval - minval
    for y in range(rect.min.y, rect.max.y+1):
        f = (y - rect.min.y) / float(rect.height)
        val = minval + f * delta
        color = color_func(minval, maxval, val, color_palette)
        draw.line([(rect.min.x, y), (rect.max.x, y)], fill=color)

color_palette = [BLUE, GREEN, RED]
region = Rect(0, 0, 730, 350)
imgx, imgy = region.max.x+1, region.max.y+1
image = Image.new("RGB", (imgx, imgy), WHITE)
draw = ImageDraw.Draw(image)
vert_gradient(draw, region, gradient_color, color_palette)
image.show()
#image.save("vert_gradient.png", "PNG")
#print 'image saved'

这是它生成并显示的图像:

screenshot of gradient image created

这将插入RGB色彩空间中的中间色彩,但可以使用其他色彩空间-例如,请参见我对问题Range values to pseudocolor的回答。

可以轻松扩展以生成ARGB(Alpha + RGB)图像。


0
投票

这里是详细说明的技术。您需要2层相互叠加,每种颜色一层。然后,使透明度增加,顶层增加,透明度减少。对于额外的作业,您可以将透明率更改为对数比例而不是线性比例。玩得开心。

© www.soinside.com 2019 - 2024. All rights reserved.