此例中需要使用HSL(色调、饱和度、亮度)类来进行转换,以下是HSL与RGB类之间的定义与转换。
HSL类代码:
1
/// <summary>
2
/// HSL类
3
/// </summary>
4
public class HSL
5
{
6
public int Hue;
7
public double Saturation;
8
public double Luminance;
9
10
public HSL()
11
{
12
}
13
14
/// <summary>
15
/// 转换到RGB
16
/// </summary>
17
/// <returns></returns>
18
public RGB ToColor()
19
{
20
if ( this.Saturation == 0 )
21
{
22
23
return new RGB((byte)( this.Luminance * 255 ));
24
}
25
else
26
{
27
double v1, v2;
28
double hue = (double) this.Hue / 360;
29
30
v2 = ( this.Luminance < 0.5 ) ?
31
( this.Luminance * ( 1 + this.Saturation ) ) :
32
( ( this.Luminance + this.Saturation ) - ( this.Luminance * this.Saturation ) );
33
v1 = 2 * this.Luminance - v2;
34
35
byte Red = (byte)( 255 * Hue_2_RGB( v1, v2, hue + ( 1.0 / 3 ) ) );
36
byte Green = (byte)( 255 * Hue_2_RGB( v1, v2, hue ) );
37
byte Blue = (byte)( 255 * Hue_2_RGB( v1, v2, hue - ( 1.0 / 3 ) ) );
38
return new RGB(Red, Green, Blue);
39
}
40
}
41
42
/// <summary>
43
/// 从RGB获取
44
/// </summary>
45
/// <param name="rgb"></param>
46
public void FormRGB(RGB rgb)
47
{
48
double r = ( rgb.Red / 255.0 );
49
double g = ( rgb.Green / 255.0 );
50
double b = ( rgb.Blue / 255.0 );
51
52
double min = Math.Min( Math.Min( r, g ), b );
53
double max = Math.Max( Math.Max( r, g ), b );
54
double delta = max - min;
55
56
this.Luminance = ( max + min ) / 2;
57
58
if ( delta == 0 )
59
{
60
this.Hue = 0;
61
this.Saturation = 0.0;
62
}
63
else
64
{
65
this.Saturation = ( this.Luminance < 0.5 ) ? ( delta / ( max + min ) ) : ( delta / ( 2 - max - min ) );
66
67
double del_r = ( ( ( max - r ) / 6 ) + ( delta / 2 ) ) / delta;
68
double del_g = ( ( ( max - g ) / 6 ) + ( delta / 2 ) ) / delta;
69
double del_b = ( ( ( max - b ) / 6 ) + ( delta / 2 ) ) / delta;
70
double hue;
71
72
if ( r == max )
73
hue = del_b - del_g;
74
else if ( g == max )
75
hue = ( 1.0 / 3 ) + del_r - del_b;
76
else
77
hue = ( 2.0 / 3 ) + del_g - del_r;
78
79
if ( hue < 0 )
80
hue += 1;
81
if ( hue > 1 )
82
hue -= 1;
83
84
this.Hue = (int) ( hue * 360 );
85
}
86
}
87
88
private double Hue_2_RGB(double v1, double v2, double vH)
89
{
90
if ( vH < 0 )
91
vH += 1;
92
if ( vH > 1 )
93
vH -= 1;
94
if ( ( 6 * vH ) < 1 )
95
return ( v1 + ( v2 - v1 ) * 6 * vH );
96
if ( ( 2 * vH ) < 1 )
97
return v2;
98
if ( ( 3 * vH ) < 2 )
99
return ( v1 + ( v2 - v1 ) * ( ( 2.0 / 3 ) - vH ) * 6);
100
return v1;
101
}
102
103
public HSL(int hue, double saturation, double luminance)
104
{
105
this.Hue = hue;
106
this.Saturation = saturation;
107
this.Luminance = luminance;
108
}
109
}
RGB类代码:
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

1
public class RGB
2
{
3
public byte Red;
4
public byte Green;
5
public byte Blue;
6
7
public System.Drawing.Color Color
8
{
9
get { return Color.FromArgb(Red, Green, Blue); }
10
set
11
{
12
Red = value.R;
13
Green = value.G;
14
Blue = value.B;
15
}
16
}
17
18
public RGB()
19
{
20
}
21
22
public RGB(byte red, byte green, byte blue)
23
{
24
this.Red = red;
25
this.Green = green;
26
this.Blue = blue;
27
}
28
29
public RGB(System.Drawing.Color color)
30
{
31
this.Red = color.R;
32
this.Green = color.G;
33
this.Blue = color.B;
34
}
35
36
public RGB(byte Value)
37
{
38
this.Red = Value;
39
this.Green = Value;
40
this.Blue = Value;
41
}
42
}
实现代码:
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

1
public static bool Hue(Bitmap b, int Value)
2
{
3
if(Value < 0 || Value > 360)return false;
4
BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height),
5
ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
6
int stride = bmData.Stride;
7
System.IntPtr Scan0 = bmData.Scan0;
8
unsafe
9
{
10
byte * p = (byte *)(void *)Scan0;
11
int nOffset = stride - b.Width*3;
12
for(int y=0;y<b.Height;++y)
13
{
14
for(int x=0; x < b.Width; ++x )
15
{
16
RGB rgb = new RGB(p[2], p[1], p[0]);
17
HSL hsl = new HSL();
18
hsl.FormRGB(rgb);
19
hsl.Hue = Value;
20
rgb = hsl.ToColor();
21
p[0] = rgb.Blue;
22
p[1] = rgb.Green;
23
p[2] = rgb.Red;
24
p += 3;
25
}
26
p += nOffset;
27
}
28
}
29
b.UnlockBits(bmData);
30
return true;
31
}

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
