绘制色调、饱和度渐变排列的图像(利用Python实现)

思路:

绘制色调、饱和度渐变排列的图像 —> 随着图像像素坐标的变换,色调的值、饱和度的值按一定规律变化即可 —> 利用循环,随着像素坐标变化,赋予不同
的色调,饱和度的值

PIL的ImageDraw模块中的point函数可以对图像单个像素赋予hsl形式的值,使用的格式为:

ImageDraw.point(xy, fill=None)

其中xy是表示坐标的元组,fill是填充的颜色

我们需要利用色调和饱和度的信息,PIL库中定义HSL类型颜色的用法为:
color = hsl(hue, saturation%, lightness%) 需要注意的是颜色的定义由字符串给出,所以实际使用中的形式为:

fill='hsl(%d,%d%%,%d%%)'%(hue,saturation,luminance)

其中,色调是给定的颜色为0到360之间的角度(红色=0,绿色=120,蓝色=240),饱和度为0%到100%之间的值(灰色=0%,全色=100%),明度为0%到100%之间的值

首先导入相应的package

我使用使用anaconda创建了名为DIP的虚拟环境,然后安装了pillow、matplotlib等常用的库
PIL库用来绘制图像,matplot库用来显示生成的结果,math库引入一些数学计算方法

from PIL import Image, ImageDraw  
from matplotlib import pyplot as plt
import numpy as np
import math

绘制矩形颜色渐变图

def rectangle_colormap(width,length,intensity):
    """
    绘制矩形颜色渐变图函数
    input:
    :width:生成图片的宽
    :length:生成图片的长
    :intensity:colormap的强度
    ouput:
    :image:颜色渐变图
    """
    matrix = 255*np.ones((width,length,3),dtype='uint8')
    image = Image.fromarray(matrix)
    # 生成一个Draw类的名为draw的对象
    draw = ImageDraw.Draw(image)
    # 利用循环,改变像素的色调和饱和度的信息,达到渐变的效果
    for y in range (0,width):
        for x in range (0,length):
            hue = x/length*360
            saturation = y/width*100
            draw.point([x, y], fill='hsl(%d,%d%%,%d%%)'%(hue,saturation,intensity))
    return image

# 设置图像的长和宽
plt.figure(figsize=(12, 12))

width,length = 40, 50
image1 = rectangle_colormap(width,length,40)
plt.subplot(221)
plt.imshow(image1)
plt.title('width=40,length = 50, intensity = 40')

image2 = rectangle_colormap(width,length,70)
plt.subplot(222)
plt.imshow(image2)
plt.title('width=40,length = 50, intensity = 70')

width,length = 60, 80
image3 = rectangle_colormap(width,length,30)
plt.subplot(223)
plt.imshow(image3)
plt.title('width=60,length = 80, intensity = 30')

image4 = rectangle_colormap(width,length,50)
plt.subplot(224)
plt.imshow(image4)
plt.title('width=60,length = 80, intensity = 50')

plt.show()

怎么让颜色渐变python python画图渐变颜色_Image

绘制圆盘状颜色变换图

整体思路与绘制矩形颜色渐变图一致,先生成一个[-1,1]之间的数组,间距为0.01(保证采样的精度,防止出现像素感),然后先生成直角坐标,最后转化为极坐标,色度随着角度发生变换,饱和度随着半径增加而增加

def cart2pol(x, y):
    """
    实现直角坐标和极坐标之间的坐标转换
    """
    rho = np.sqrt(x**2 + y**2)
    phi = np.arctan2(y, x)
    return(rho, phi)

def circular_colormap(radis,intensity):
    """
    input:
    :radis: 圆形颜色渐变图的半径大小    
    :intensity: 圆形渐变图的整体强度大小     
    return:
    :image: 圆形渐变图
    """
    x = np.arange(-radis, radis, radis/100)
    y = np.arange(-radis, radis, radis/100)
    xx, yy = np.meshgrid(x, y)
    rhp, phi = cart2pol(xx, yy)

    matrix2 = 255*np.zeros((xx.shape[0],xx.shape[1],3),dtype='uint8')
    image = Image.fromarray(matrix2)
    draw = ImageDraw.Draw(image)
    phi += math.pi
    for x in range (0,xx.shape[0]):
        for y in range (0,xx.shape[1]):
            if rhp[x,y]<1:
                saturation = rhp[x,y]/1*100
                hue = phi[x,y]/(2*math.pi)*360
                draw.point([x, y], fill='hsl(%d,%d%%,%d%%)'%(hue,saturation,intensity))
    return image

# 设置图像的长和宽
plt.figure(figsize=(12, 12))

width,length = 40, 50
image1 = circular_colormap(1,40)
plt.subplot(221)
plt.imshow(image1)
plt.title('radis = 1,intensity = 40')

image2 = circular_colormap(1,60)
plt.subplot(222)
plt.imshow(image2)
plt.title('radis = 1,intensity = 60')

width,length = 60, 80
image3 = circular_colormap(1.5,40)
plt.subplot(223)
plt.imshow(image3)
plt.title('radis = 1.5,intensity = 40')

image4 = circular_colormap(1.5,60)
plt.subplot(224)
plt.imshow(image4)
plt.title('radis = 1.5,intensity = 60')

plt.show()

怎么让颜色渐变python python画图渐变颜色_颜色渐变_02

参考资料

PIL图像处理库关于HSL颜色赋值
https://pillow.readthedocs.io/en/stable/reference/ImageColor.html?highlight=hsl stackoverflow关于HSL颜色赋值的使用
https://stackoverflow.com/questions/17049777/hsl-python-syntax-pil