<p>这里有三种方法来做这个双线性插值。第一个版本用纯Python完成所有的算法,第二个版本使用<a href="https://python-pillow.org/" rel="nofollow noreferrer">PIL</a>图像合成,第三个版本使用Numpy来完成算法。正如预期的那样,纯Python比其他方法慢得多。Numpy版本(源于<a href="https://stackoverflow.com/users/5067311/andras-deak">Andras Deak</a>编写的代码)几乎与小图像的PIL版本一样快,但是对于较大的图像,PIL版本明显更快。在</p>
<p>我也尝试在PIL中使用jadsq的缩放技术,但结果并不理想-我怀疑PIL的插值代码有点缺陷。在</p>
<p>如果您想创建大量相同大小的双线性渐变图像,PIL技术还有另一个优势:一旦您创建了构图遮罩,就不需要为每个图像重建它们。在</p>
<pre><code>#!/usr/bin/env python3
''' Simple bilinear interpolation
Written by PM 2Ring 2016.09.14
'''
from PIL import Image
from math import floor
import numpy as np
def color_square0(colors, size):
tl, tr, bl, br = colors
m = size - 1
r = range(size)
def interp_2D(tl, tr, bl, br, x, y):
u0, v0 = x / m, y / m
u1, v1 = 1 - u0, 1 - v0
return floor(0.5 + u1*v1*tl + u0*v1*tr + u1*v0*bl + u0*v0*br)
data = bytes(interp_2D(tl[i], tr[i], bl[i], br[i], x, y)
for y in r for x in r for i in (0, 1, 2))
return Image.frombytes('RGB', (size, size), data)
# Fastest
def color_square1(colors, size):
#Make an Image of each corner color
tl, tr, bl, br = [Image.new('RGB', (size, size), color=c) for c in colors]
#Make the composition mask
mask = Image.new('L', (size, size))
m = 255.0 / (size - 1)
mask.putdata([int(m * x) for x in range(size)] * size)
imgt = Image.composite(tr, tl, mask)
imgb = Image.composite(br, bl, mask)
return Image.composite(imgb, imgt, mask.transpose(Image.TRANSPOSE))
# This function was derived from code written by Andras Deak
def color_square2(colors, size):
tl, tr, bl, br = map(np.array, colors)
m = size - 1
x, y = np.mgrid[0:size, 0:size]
x = x[..., None] / m
y = y[..., None] / m
data = np.floor(x*y*br + (1-x)*y*tr + x*(1-y)*bl + (1-x)*(1-y)*tl + 0.5)
return Image.fromarray(np.array(data, dtype = 'uint8'), 'RGB')
color_square = color_square1
#tl = (255, 0, 0)
#tr = (255, 255, 0)
#bl = (0, 0, 255)
#br = (0, 255, 0)
tl = (108, 115, 111)
tr = (239, 239, 192)
bl = (124, 137, 129)
br = (192, 192, 175)
colors = (tl, tr, bl, br)
size = 256
img = color_square(colors, size)
img.show()
#img.save('test.png')
</code></pre>
<p><strong>输出</strong></p>
<p><img src="https://i.stack.imgur.com/CswYU.png" alt="bilinear gradient"/></p>
<hr/>
<p>为了好玩,这里有一个使用Tkinter的简单GUI程序,可以用来生成这些渐变。在</p>
^{pr2}$