Python colorsys 怎样在 RGB 与 HLS 之间转换
如果手里拿的是常见的 (R, G, B) 三通道整数,Python 标准库 colorsys 的正确用法是:先把每个通道除以 255 归一化,再调用 rgb_to_hls;需要显示或保存时,使用 hls_to_rgb 转回 0 到 1 的 RGB,最后再裁剪、四舍五入到 0 到 255。
最容易出错的地方有两个:colorsys接受的是 0 到 1 的浮点数,HLS 元组顺序是(h, l, s),不是 HSV 的(h, s, v)。
官方文档:https://docs.python.org/3/library/colorsys.html
先分清 colorsys 的数值范围
colorsys 同时提供 RGB、YIQ、HLS 和 HSV 之间的双向转换。对 RGB、HLS、HSV 来说,坐标都使用 0 到 1 的浮点数;因此网页颜色常见的 255 不能直接作为参数传入。
HLS 的三个位置分别是色相 h、亮度 l、饱和度 s。其中色相也是 0 到 1 的归一化坐标,如果业务界面需要角度,可以把它乘以 360;亮度和饱和度则继续保持 0 到 1。

最小配方:RGB 转 HLS
先写一个只负责换算的函数,把外部常见的 8 位 RGB 和 colorsys 的内部坐标隔离开。这样后面无论颜色来自表单、接口还是图片元数据,都不会把两种尺度混在一起。
import colorsys
def rgb255_to_hls(rgb):
# 把外部常见的 0 到 255 通道转换为 colorsys 使用的 0 到 1 浮点数。
normalized = tuple(channel / 255 for channel in rgb)
# HLS 的返回顺序固定是 hue、lightness、saturation。
return colorsys.rgb_to_hls(*normalized)
color_hls = rgb255_to_hls((52, 152, 219))
# h 是 0 到 1 的色相坐标,乘 360 后更适合在角度界面中展示。
print(color_hls[0] * 360, color_hls[1], color_hls[2])
这个配方的关键不是把除法写在一行,而是明确边界:函数输入是 0 到 255,函数输出是 (h, l, s)。调用方如果需要色相角度,只在展示层转换,不要把角度再传回 hls_to_rgb。
HLS 里的亮度和饱和度怎样调整
HLS 适合表达“保持大致色相,只把颜色调亮一点”这类操作。可以先解包元组,再限制调整后的亮度和饱和度仍在 0 到 1。色相通常按环形坐标处理,超过 1 或小于 0 时用取模回到这个范围。
def shift_hls(hls, lightness_delta=0.0, saturation_delta=0.0):
h, l, s = hls
# 色相是环形坐标,取模可以处理超过 1 或小于 0 的情况。
h = h % 1.0
# 亮度和饱和度是区间值,调整后要限制在合法范围内。
l = min(1.0, max(0.0, l + lightness_delta))
s = min(1.0, max(0.0, s + saturation_delta))
return h, l, s
brighter = shift_hls(color_hls, lightness_delta=0.08)
# brighter 仍然是 colorsys 可以接受的 (h, l, s) 三元组。
print(brighter)
这里的“限制”是业务层保护,不是 colorsys 额外提供的校验器。把参数集中在一个小函数里,能避免多个页面分别处理边界,最后出现同一颜色在不同页面亮度不一致的情况。
调整 HLS 后怎样转回 RGB
hls_to_rgb 返回的三个通道仍然是 0 到 1 的浮点数。要交给 CSS、JSON 接口或图像库时,再统一乘以 255,并用 round 得到整数。乘法前后都保留裁剪,可以防止浮点误差把边界推到合法范围之外。

def hls_to_rgb255(hls):
h, l, s = hls
# hls_to_rgb 要求 h、l、s 都是 0 到 1 的坐标,而不是色相角度。
rgb01 = colorsys.hls_to_rgb(h % 1.0, l, s)
# 裁剪并四舍五入,得到 CSS 或接口常用的 8 位整数通道。
return tuple(round(min(1.0, max(0.0, channel)) * 255) for channel in rgb01)
rgb255 = hls_to_rgb255(brighter)
print(rgb255)
如果你要生成 CSS,可以把结果拼成 rgb(r g b);如果接口约定的是小数 RGB,则不要做最后的乘 255,直接保留 rgb01 即可。
HLS 和 HSV 不要把位置顺序混用
同一个模块里还有 rgb_to_hsv 和 hsv_to_rgb。HLS 使用 (h, l, s),HSV 使用 (h, s, v),第二、第三个值的含义不同。把 HSV 元组直接传给 HLS 的逆转换,代码通常不会报错,却会得到明显不同的颜色。
| 目标 | 调用 | 返回顺序 | 坐标范围 |
|---|---|---|---|
| RGB 转 HLS | rgb_to_hls(r, g, b) | h, l, s | 都在 0 到 1 |
| HLS 转 RGB | hls_to_rgb(h, l, s) | r, g, b | 都在 0 到 1 |
| RGB 转 HSV | rgb_to_hsv(r, g, b) | h, s, v | 都在 0 到 1 |
几个实际使用时容易踩到的坑
- 把 0 到 255 直接传入。先在入口归一化,返回显示值时再反向换算。
- 把色相角度传给逆函数。界面上的 180 度要先除以 360,才能成为
colorsys的h。 - 混淆 HLS 和 HSV 的顺序。看到第二个值时先确认它是 lightness 还是 saturation。
- 忽略灰度色。当饱和度接近 0 时,色相对视觉颜色区分的作用很弱,业务上不应依赖灰度色的 h 值做分类。
- 直接截断浮点数。显示层优先使用
round,并在乘 255 前后保持 0 到 1 的边界保护。
可以直接复用的完整片段
如果项目只需要一条稳定的 RGB/HLS 往返路径,可以把归一化、调整和反归一化收拢成下面这个小工具。它不负责读取图片文件,输入输出也保持为普通 Python 元组,便于在 Web 接口或颜色选择器中复用。
import colorsys
def rgb255_to_hls(rgb):
# 统一把 8 位 RGB 通道送入 0 到 1 的标准库坐标。
r, g, b = (channel / 255 for channel in rgb)
return colorsys.rgb_to_hls(r, g, b)
def hls_to_rgb255(hls):
h, l, s = hls
# 亮度和饱和度由调用方控制,色相按环形坐标归一化。
rgb01 = colorsys.hls_to_rgb(h % 1.0, l, s)
# 将标准库输出转换为可显示的整数 RGB,并抵抗边界浮点误差。
return tuple(round(min(1.0, max(0.0, value)) * 255) for value in rgb01)
original = (52, 152, 219)
hls = rgb255_to_hls(original)
# 只调整亮度,保持色相和饱和度的业务含义不变。
adjusted_hls = (hls[0], min(1.0, hls[1] + 0.08), hls[2])
adjusted_rgb = hls_to_rgb255(adjusted_hls)
print(adjusted_rgb)
这套写法的边界很清楚:输入输出层使用 0 到 255,转换层使用 0 到 1,HLS 内部始终按 h、l、s 解包。后续如果换成 HSV,只需要同时替换函数名和元组语义,不要只改一个调用点。
相关问题
colorsys 的色相为什么不是 0 到 360?
它把色相也表示为 0 到 1 的归一化坐标。需要角度时在展示边界乘以 360,传回转换函数前再除以 360。
能不能把十六进制颜色直接传给 colorsys?
不能直接传入。先把十六进制拆成三个 0 到 255 的通道,再按本文的归一化方式转换。
只想调亮颜色,为什么不直接给 RGB 每个通道加值?
直接改 RGB 会同时改变颜色的综合色相和饱和度。先转到 HLS,可以把亮度调整表达得更清楚,再统一转回显示通道。
Java PropertyChangeSupport 怎样只监听指定属性
- 上一篇
- Java PropertyChangeSupport 怎样只监听指定属性
- 下一篇
- JavaScript DocumentFragment 插入文档后为什么变成空片段
-
- 文章 · python教程 | 37分钟前 |
- Python colorsys 为什么不能直接接收零到二百五十五的 RGB 值
- 123浏览 收藏
-
- 文章 · python教程 | 1小时前 | 标准库 · 持久化 · python · Python Cookiejar expires http.CookieJar FileCookieJar ignore_expires
- Python CookieJar 的过期过滤与 ignore_expires 有什么区别
- 330浏览 收藏
-
- 文章 · python教程 | 1小时前 | 标准库 · python · Cookiejar Python MozillaCookieJar cookies.txt Python保存Cookie
- Python MozillaCookieJar 怎样把 Cookie 保存到本地文件
- 299浏览 收藏
-
- 文章 · python教程 | 2小时前 |
- Python headerregistry 的 defects 怎样保留邮件头解析问题
- 309浏览 收藏
-
- 文章 · python教程 | 2小时前 |
- Python headerregistry 怎样保留地址组名称与组内收件人
- 360浏览 收藏
-
- 文章 · python教程 | 3小时前 |
- Python plistlib 怎样把配置写成二进制 plist
- 491浏览 收藏
-
- 文章 · python教程 | 4小时前 | python · Python MIME quoted-printable quopri Q编码 邮件头
- Python quopri 的 header 参数为什么改变下划线含义
- 491浏览 收藏
-
- 文章 · python教程 | 4小时前 | python · Python MIME quoted-printable quopri 邮件正文
- Python quopri 怎样解码带软换行的邮件正文
- 147浏览 收藏
-
- 文章 · python教程 | 5小时前 |
- Python imaplib 怎样用 UID 获取邮件而不依赖序号
- 413浏览 收藏
-
- 文章 · python教程 | 1天前 |
- Python importlib.metadata.entry_points 怎样按组选择插件入口
- 154浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 797次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 787次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 875次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 845次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 677次使用
-
- GScript 编写标准库示例详解
- 2022-12-30 369浏览
-
- 关于Golang标准库flag的全面讲解
- 2023-02-25 344浏览
-
- Golang标准库unsafe源码解读
- 2022-12-29 464浏览
-
- 快速掌握Go语言HTTP标准库的实现方法
- 2022-12-30 327浏览
-
- Go语言利用ffmpeg转hls实现简单视频直播
- 2022-12-24 440浏览

