如何实现8位RGB颜色到24位RGB颜色的转换(Python版)
8位RGB转24位RGB可行性结论
完全可行。你要求转换后保留256种颜色的限制,刚好匹配8位单字节值0-255的取值范围,不需要做颜色插值或者降采样,转换过程相对于8位源的色彩范围无信息损失。
通用转换规则与公式
目前最常用的无调色板8位RGB转24位方案采用3:3:2位分配逻辑——基于人眼对三原色的敏感度差异,将单字节的8个数据位拆分给三个颜色分量:
- 高3位分配给红色分量(R)
- 中间3位分配给绿色分量(G)
- 低2位分配给蓝色分量(B)
转换时将每个短位长的分量线性拉伸到8位(取值范围0-255)即可,具体公式如下(输入8位值记为c,取值0-255):
- 红色分量:
R = ((c >> 5) & 0b111) * 255 // 7 - 绿色分量:
G = ((c >> 2) & 0b111) * 255 // 7 - 蓝色分量:
B = (c & 0b11) * 255 // 3
如果你的8位颜色值是基于固定调色板(比如老式VGA 256色、自定义业务调色板)生成的,转换逻辑更简单:直接把8位值作为索引,查表获取对应的24位RGB三元组即可,输出颜色数量固定为256种,完全符合你的要求。
Python可直接调用实现
3:3:2无调色板版本
不需要额外依赖,传入0-255的8位颜色值即可返回24位RGB三元组:
def rgb8_to_rgb24(rgb8_val: int) -> tuple[int, int, int]: """ 8位RGB值转24位RGB三元组,采用3:3:2位分配规则,固定输出256种颜色 :param rgb8_val: 0-255区间的8位源颜色值 :return: (R, G, B)三元组,每个分量取值范围0-255 """ if not 0 <= rgb8_val <= 255: raise ValueError("输入的8位颜色值必须在0-255范围内") r = ((rgb8_val >> 5) & 0b111) * 255 // 7 g = ((rgb8_val >> 2) & 0b111) * 255 // 7 b = (rgb8_val & 0b11) * 255 // 3 return (r, g, b)
调色板查表版本
适配带调色板的8位颜色场景,可替换为自定义调色板:
# 可替换为自定义调色板,格式为长度256的列表,索引对应8位颜色值,元素为(R,G,B)三元组 VGA_DEFAULT_PALETTE = [ (0, 0, 0), (0, 0, 170), (0, 170, 0), (0, 170, 170), (170, 0, 0), (170, 0, 170), (170, 85, 0), (170, 170, 170), (85, 85, 85), (85, 85, 255), (85, 255, 85), (85, 255, 255), (255, 85, 85), (255, 85, 255), (255, 255, 85), (255, 255, 255), # 剩余240个色值可根据实际使用的调色板标准补全 ] def rgb8_to_rgb24_palette( rgb8_val: int, palette: list[tuple[int, int, int]] = VGA_DEFAULT_PALETTE ) -> tuple[int, int, int]: """ 基于调色板的8位RGB转24位RGB实现 :param rgb8_val: 0-255区间的8位源颜色值 :param palette: 长度为256的调色板列表 :return: (R, G, B)三元组,每个分量取值范围0-255 """ if not 0 <= rgb8_val <= 255: raise ValueError("输入的8位颜色值必须在0-255范围内") if len(palette) != 256: raise ValueError("调色板必须包含恰好256个RGB颜色值") return palette[rgb8_val]
调用示例:
rgb8_to_rgb24(0)返回(0,0,0)(纯黑),rgb8_to_rgb24(255)返回(255,255,255)(纯白)。
内容的提问来源于stack exchange,提问作者DavidCZ2051
相关产品推荐
相关产品推荐

