RGB HSV HLS三种色彩模式转换(C语言实现)
2023-09-11 14:17:59 时间
Android项目上处理图像的代码(注释全部去掉)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
|
void RGB2HSV( uint16_t * h, uint16_t * s, uint16_t * v, uint8_t r, uint8_t g, uint8_t b) { double rr, gg, bb; double hh, ss, vv; double cmax, cmin, cdes; rr = r; gg = g; bb = b; cmax = (rr > gg) ? rr : gg; if (bb > cmax) { cmax = bb; } cmin = (rr < gg) ? rr : gg; if (bb < cmin) { cmin = bb; } cdes = cmax - cmin; vv = cmax; if (cdes != 0) { ss = cdes * SCALE / cmax; if (cmax == rr) { hh = (gg - bb) * SCALE / cdes; } else if (cmax == gg) { hh = (bb - rr) * SCALE / cdes + 2 * H_SCALE; } else { hh = (rr - gg) * SCALE / cdes + 4 * H_SCALE; } } else if (cmax != 0) { ss = cdes * SCALE / cmax; hh = 0; } else { ss = 0; hh = 0; } if (hh < 0) { hh += 6 * H_SCALE; } *h = hh * H_GETA; *s = ss * H_GETA; *v = vv * H_GETA; } void HSV2RGB( uint8_t *r, uint8_t *g, uint8_t *b, uint16_t h, uint16_t s, uint16_t v) { double rr = 0, gg = 0, bb = 0; double hh, ss, vv; if (h == 6 * H_GETA * H_SCALE) { h = 0; } hh = ( double )h / H_GETA; ss = ( double )s / GETA; vv = ( double )v / GETA; switch (( int )(hh / H_SCALE)) { case 0: rr = SCALE; gg = hh; bb = 0; break ; case 1: rr = 2 * H_SCALE - hh; gg = SCALE; bb = 0; break ; case 2: rr = 0; gg = SCALE; bb = hh - 2 * H_SCALE; break ; case 3: rr = 0; gg = 4 * H_SCALE - hh; bb = SCALE; break ; case 4: rr = hh - 4 * H_SCALE; gg = 0; bb = SCALE; break ; case 5: rr = SCALE; gg = 0; bb = 6 * H_SCALE - hh; break ; } rr = (rr + (SCALE - rr) * (SCALE - ss) / SCALE) * vv / SCALE; gg = (gg + (SCALE - gg) * (SCALE - ss) / SCALE) * vv / SCALE; bb = (bb + (SCALE - bb) * (SCALE - ss) / SCALE) * vv / SCALE; *r = rr; *g = gg; *b = bb; if (*r > 255)*r = 255; if (*g > 255)*g = 255; if (*b > 255)*b = 255; } void RGB2HLS( double *h, double *l, double *s, uint8_t r, uint8_t g, uint8_t b) { double dr = ( double )r/255; double dg = ( double )g/255; double db = ( double )b/255; double cmax = MAX(dr, MAX(dg, db)); double cmin = MIN(dr, MIN(dg, db)); double cdes = cmax - cmin; double hh, ll, ss; ll = (cmax+cmin)/2; if (cdes){ if (ll <= 0.5) ss = (cmax-cmin)/(cmax+cmin); else ss = (cmax-cmin)/(2-cmax-cmin); if (cmax == dr) hh = (0+(dg-db)/cdes)*60; else if (cmax == dg) hh = (2+(db-dr)/cdes)*60; else // if(cmax == b) hh = (4+(dr-dg)/cdes)*60; if (hh<0) hh+=360; } else hh = ss = 0; *h = hh; *l = ll; *s = ss; } void HLS2RGB( uint8_t *r, uint8_t *g, uint8_t *b, double h, double l, double s) { double cmax,cmin; if (l <= 0.5) cmax = l*(1+s); else cmax = l*(1-s)+s; cmin = 2*l-cmax; if (s == 0){ *r = *g = *b = l*255; } else { *r = HLS2RGBvalue(cmin,cmax,h+120)*255; *g = HLS2RGBvalue(cmin,cmax,h)*255; *b = HLS2RGBvalue(cmin,cmax,h-120)*255; } } double HLS2RGBvalue( double n1, double n2, double hue) { if (hue > 360) hue -= 360; else if (hue < 0) hue += 360; if (hue < 60) return n1+(n2-n1)*hue/60; else if (hue < 180) return n2; else if (hue < 240) return n1+(n2-n1)*(240-hue)/60; else return n1; } |
相关文章
- C语言的有符号与无符号,二进制整数的扩展与截断
- 常见的C语言编程规范
- C语言入坑指南-缓冲区溢出
- 常量和字符串(C语言初阶细致)
- 《21天学通C语言(第6版•修订版)》一第1章 C语言概览1.1 C语言简史
- 【C语言】九九乘法口诀表
- 【C语言】时间戳转换为年月日时分秒和年月日时分秒转换为时间戳,计算星期几和过去的天数(格林威治时间1970-01-01)
- C语言 —— 贪吃蛇
- 《C语言解惑》—— 第1章 初涉C语言者的困惑
- C语言基本输入输出程序设计——计算当前时间and转换大写姓名and工资信息表
- 牛客网C语言语法篇练习之习题集(4)
- C语言实现Lagrange插值(用于插值组合导航结果)
- C语言实现方向余弦矩阵转欧拉角和姿态四元数
- C语言内存管理 static
- 编程参考 - C语言中将字符串转换为整数
- C语言中的数组的访问方式
- C语言-------将字符串反向排列