Python PIL:生成垂直梯度图像

Python PIL:生成垂直梯度图像,python,python-imaging-library,gradient,Python,Python Imaging Library,Gradient,在Android中,我使用以下代码生成我需要的渐变背景: 背景从上到下从浅到相对暗。我想知道如何在Python中使用PIL实现同样的效果,因为我需要在另一个用Python编写的程序中使用相同的效果。下面是详细说明的技术。你需要两层在彼此的上面,每种颜色一层。然后使顶层的透明度增加,底层的透明度减少。对于额外的作业,您可以将透明度更改为递增的对数比例,而不是线性比例。玩得开心。这里展示了绘制多色矩形水平和垂直渐变的方法 from PIL import Image, ImageDraw BLA

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



背景从上到下从浅到相对暗。我想知道如何在Python中使用PIL实现同样的效果,因为我需要在另一个用Python编写的程序中使用相同的效果。

下面是详细说明的技术。你需要两层在彼此的上面,每种颜色一层。然后使顶层的透明度增加,底层的透明度减少。对于额外的作业,您可以将透明度更改为递增的对数比例,而不是线性比例。玩得开心。

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

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'
从PIL导入图像,ImageDraw
黑色、暗灰色=((0,0,0)、(63,63,63)、(127127))
浅灰色,白色=((191),(255255))
蓝色,绿色,红色=((0,0,255),(0,255,0),(255,0,0))
类点(对象):
定义初始化(self,x,y):
self.x,self.y=x,y
@静力学方法
来自_点的def(其他):
返回点(其他.x,其他.y)
类Rect(对象):
定义初始化(self,x1,y1,x2,y2):
如果x1
这是它生成并显示的图像:

这会在RGB颜色空间中插入中间颜色,但也可以使用其他颜色空间-例如,请参见我对问题的回答


这可以很容易地扩展以生成ARGB(Alpha+RGB)图像。

如果您只需要两种颜色,这可以非常简单地完成:

def生成梯度(
color1:str,color2:str,宽度:int,高度:int)->图像:
“”“生成垂直渐变。”“”
基本=图像。新('RGB',(宽度,高度),颜色1)
顶部=图像。新('RGB',(宽度,高度),颜色2)
掩码=图像。新建('L',(宽度,高度))
掩码_数据=[]
对于范围内的y(高度):
对于范围内的x(宽度):
掩码_数据追加(整数(255*(y/高度)))
mask.putdata(mask_数据)
底部。粘贴(顶部,(0,0),遮罩)
返回基地

这将在每种颜色中创建一层,然后创建一个透明度根据
y
位置变化的遮罩<代码>y/高度
x/宽度
在第10行中,对于水平梯度,或
x
y
的任何函数,对于另一个梯度。

RGB值由
产生的结果是什么?@martineau looks(160、160、160)是最接近的。谢谢。垂直方向有多少像素?你会在意它是用Numpy还是scipy吗?从我刚才的文档来看,这没有多大意义。它看起来更像是ARGB值为(64,0,0,0)的对象。还有,你知道需要多大的图像吗?@martineau它是640*640。谢谢!我刚才复制并粘贴了您的代码,收到了以下错误:
delta=1:^SyntaxError:无效语法(删除
(冒号)可解决此错误)。我使用的是Python2.7.12,但我不认为这就是原因。伟大的成像顺便说一句@Wineunuchs2Unix:谢谢你的补充和提醒。当我试图清理其他人为处理
delta
为零修正所做的一些更改时,代码被弄乱了。谢谢更新。我刚刚在这个网站上链接到了你的答案:@wineunuchs2unix:很高兴听到这个消息-对于占位符来说似乎需要很多努力,但是我该判断谁呢…
;-)