rgb hsl转换
The most common ways of encoding colour values are RGB (red, green and blue) and HSL (hue, saturation and lightness). In this article I will show how you can convert between the two in Python.
编码颜色值的最常见方法是RGB(红色,绿色和蓝色)和HSL(色相,饱和度和亮度)。 在本文中,我将展示如何使用Python在两者之间进行转换。
A while ago I wrote a C library to convert RGB (red/green/blue) values to HSL (hue/saturation/lightness) and back again. As part of a project which I am planning I need to be able to do the same in Python and was intending to re-write the C in Python, or probably Cython.
不久前,我编写了一个C库,将RGB(红色/绿色/蓝色)值转换为HSL(色相/饱和度/亮度)并再次转换。 作为我计划的项目的一部分,我需要能够在Python中完成同样的工作,并打算用Python或Cython重写C。
However, I then found a module called colorsys
in an obscure corner of the Python Standard Library. This module includes functions to do the conversions I will need, and in this post I will demonstrate using them to create an array of HSL values from a Pillow image, and then convert these back to RGB to create a new identical image.
但是,我随后在Python标准库的一个晦涩角落找到了一个名为colorsys
的模块。 该模块包含执行我将需要的转换的函数,在本文中,我将演示如何使用它们从枕头图像创建HSL值数组,然后将它们转换回RGB以创建新的相同图像。
On its own this isn’t a useful thing to do but I find HSL to be more natural and intuitive than RGB, for example if you need to change an image’s saturation or lightness you can just add or subtract from the saturation or lightness respectively.
它本身并不是一件有用的事情,但是我发现HSL比RGB更自然和直观,例如,如果您需要更改图像的饱和度或亮度,则可以分别从饱和度或亮度中添加或减去。
This project consists of one short file called rgbhsl.py which you can clone/download the Github repository.
该项目包含一个名为rgbhsl.py的简短文件,您可以克隆/下载Github存储库 。
This is the source code listing for the entire file.
这是整个文件的源代码列表。
import colorsys
from PIL import Image
import numpy
def main():
print("-------------------------")
print("| codedrome.com |")
print("| RGB to HSL Conversion |")
print("-------------------------\n")
try:
image = Image.open("canterbury.jpg")
hls_array = create_hls_array(image)
new_image = image_from_hls_array(hls_array)
new_image.save("canterbury_from_hsl.jpg", quality=95)
except IOError as e:
print(e)
def create_hls_array(image):
"""
Creates a numpy array holding the hue, lightness
and saturation values for the Pillow image.
"""
pixels = image.load()
hls_array = numpy.empty(shape=(image.height, image.width, 3), dtype=float)
for row in range(0, image.height):
for column in range(0, image.width):
rgb = pixels[column, row]
hls = colorsys.rgb_to_hls(rgb[0]/255, rgb[1]/255, rgb[2]/255)
hls_array[row, column, 0] = hls[0]
hls_array[row, column, 1] = hls[1]
hls_array[row, column, 2] = hls[2]
return hls_array
def image_from_hls_array(hls_array):
"""
Creates a Pillow image from the HSL array
generated by the create_hls_array function.
"""
new_image = Image.new("RGB", (hls_array.shape[1], hls_array.shape[0]))
for row in range(0, new_image.height):
for column in range(0, new_image.width):
rgb = colorsys.hls_to_rgb(hls_array[row, column, 0],
hls_array[row, column, 1],
hls_array[row, column, 2])
rgb = (int(rgb[0]*255), int(rgb[1]*255), int(rgb[2]*255))
new_image.putpixel((column, row), rgb)
return new_image
main()
进口 (imports)
The colorsys
module is part of the Python Standard Library, but this project also uses a numpy array and the Pillow imaging library which you will need to install if you don’t already have them.
colorsys
模块是Python标准库的一部分,但是该项目还使用numpy数组和Pillow映像库,如果您还没有它们,则需要安装它们。
主要 (main)
This is just a short function to open a Pillow image, and then call functions to create our HSL array, create a new image from the array and then save it.
这只是打开Pillow图像的简短功能,然后调用函数来创建我们的HSL数组,从该数组创建一个新图像,然后保存它。
create_hls_array (create_hls_array)
Firstly we need to get an array of pixels using the Pillow image’s load
method, and also an empty three-dimensional numpy array. The first two dimensions are the rows and columns in the image, the third having a fixed size of 3 for the HSL values. The array has a float type because saturation and lightness values can contain decimal fractions.
首先,我们需要使用Pillow图片的load
方法获取一个像素数组,以及一个空的三维numpy数组。 前两个维是图像中的行和列,第三个维的HSL值的固定大小为3。 该数组具有浮点类型,因为饱和度和亮度值可以包含小数部分。
We then iterate the rows and columns of pixels in nested loops, getting an RGB tuple for each pixel before calling colorsys.rgb_to_hls
. There are two very important points to note about colorsys.rgb_to_hls
:
然后,我们在嵌套循环中迭代像素的行和列,在调用colorsys.rgb_to_hls
之前获得每个像素的RGB元组。 关于colorsys.rgb_to_hls
有两点需要注意:
- The function uses hue, lightness and saturation instead of the more usual hue, saturation and lightness 该功能使用色相,亮度和饱和度,而不是更常见的色相,饱和度和亮度
- The arguments are fractions between 0 and 1 rather than integers between 0 and 255 so we need to divide each by 255 参数是0到1之间的分数,而不是0到255之间的整数,因此我们需要将它们除以255
We then set the three third-dimension values to the hue, lightness and saturation values respectively. After the loop exits we just return the array.
然后,我们分别将三个三维值分别设置为色调,亮度和饱和度值。 循环退出后,我们只返回数组。
image_from_hls_array (image_from_hls_array)
Firstly we create a new Pillow image the same size as the numpy array, after which we effectively reverse the process carried out by create_hls_array
.
首先,我们创建一个与numpy数组大小相同的新Pillow图像,此后我们有效地逆转了create_hls_array
进行的过程。
Within nested loops for the rows and columns we call colorsys.hls_to_rgb
(again note the HLS rather than HSL) to get a tuple of RGB values. Remember these are decimals from 0 to 1 so then need to be multiplied by 255 and cast to ints. Finally we set the relevant pixel to the RGB value. After the loops we just need to return the new image.
在行和列的嵌套循环中,我们调用colorsys.hls_to_rgb
(再次注意,使用HLS而不是HSL)来获取RGB值的元组。 请记住,这些是从0到1的十进制数,因此需要乘以255并转换为整数。 最后,我们将相关像素设置为RGB值。 循环之后,我们只需要返回新图像。
You might like to experiment with changing the HLS values before using them to build a new image.
您可能想尝试更改HLS值,然后再使用它们来构建新图像。
I tried out the program with the following image which is called canterbury.jpg, and hard-coded the filename. You will probably want to use you own image so just change the open and save filenames in main
before running the program.
我使用下面的图像canterbury.jpg尝试了该程序,并对文件名进行了硬编码。 您可能需要使用自己的映像,因此在运行程序之前只需更改打开的文件名并将其保存在main
。
Run the program with this command.
使用此命令运行程序。
python3.8 rgbhsl.py
python3.8 rgbhsl.py
The program is inevitably slow as it has to read and write each pixel, but when it has run you will find a new image file identical to the original.
该程序不可避免地会很慢,因为它必须读写每个像素,但是运行后,您会发现一个与原始图像相同的新图像文件。
As I mentioned at the top this is just a small but vital part of a much larger project which I will begin to release into the wild in the coming months.
正如我在顶部提到的那样,这只是一个较大项目的一小部分,但至关重要,在接下来的几个月中我将开始将其发布。
翻译自: https://medium.com/explorations-in-python/rgb-hsl-conversions-in-python-14f457367816
rgb hsl转换