BMP每个像素都由RGB组成,用下面函数转换成色相(h)、饱和度(s)、亮度(l) 'RGB转换为色相(h)、饱和度(s)、亮度(l) Public Sub RGBToHLS( _ ByVal r As Long, ByVal g As Long, ByVal b As Long, _ h As Single, s As Single, l As Single) Dim Max As Single Dim Min As Single Dim delta As Single Dim rR As Single, rG As Single, rB As Single rR = r / 255: rG = g / 255: rB = b / 255 Max = Maximum(rR, rG, rB) Min = Minimum(rR, rG, rB) l = (Max + Min) / 2 '{This is the lightness} '{Next calculate saturation} If Max = Min Then 'begin {Acrhomatic case} s = 0 h = 0 'end {Acrhomatic case} Else 'begin {Chromatic case} '{First calculate the saturation.} If l <= 0.5 Then s = (Max - Min) / (Max + Min) Else s = (Max - Min) / (2 - Max - Min) End If '{Next calculate the hue.} delta = Max - Min If rR = Max Then h = (rG - rB) / delta '{Resulting color is between yellow and magenta} ElseIf rG = Max Then h = 2 + (rB - rR) / delta '{Resulting color is between cyan and yellow} ElseIf rB = Max Then h = 4 + (rR - rG) / delta '{Resulting color is between magenta and cyan} End If End If End Sub'色相(h)、饱和度(s)、亮度(l)转换为RGB Public Sub HLSToRGB( _ ByVal h As Single, ByVal s As Single, ByVal l As Single, _ r As Long, g As Long, b As Long) Dim rR As Single, rG As Single, rB As Single Dim Min As Single, Max As Single If s = 0 Then ' Achromatic case: rR = l: rG = l: rB = l Else ' Chromatic case: ' delta = Max-Min If l <= 0.5 Then 's = (Max - Min) / (Max + Min) ' Get Min value: Min = l * (1 - s) Else 's = (Max - Min) / (2 - Max - Min) ' Get Min value: Min = l - s * (1 - l) End If ' Get the Max value: Max = 2 * l - Min ' Now depending on sector we can evaluate the h,l,s: If (h < 1) Then rR = Max If (h < 0) Then rG = Min rB = rG - h * (Max - Min) Else rB = Min rG = h * (Max - Min) + rB End If ElseIf (h < 3) Then rG = Max If (h < 2) Then rB = Min rR = rB - (h - 2) * (Max - Min) Else rR = Min rB = (h - 2) * (Max - Min) + rR End If Else rB = Max If (h < 4) Then rR = Min rG = rR - (h - 4) * (Max - Min) Else rG = Min rR = (h - 4) * (Max - Min) + rG End If End If End If r = rR * 255: g = rG * 255: b = rB * 255 End SubPrivate Function Maximum(rR As Single, rG As Single, rB As Single) As Single If (rR > rG) Then If (rR > rB) Then Maximum = rR Else Maximum = rB End If Else If (rB > rG) Then Maximum = rB Else Maximum = rG End If End If End FunctionPrivate Function Minimum(rR As Single, rG As Single, rB As Single) As Single If (rR < rG) Then If (rR < rB) Then Minimum = rR Else Minimum = rB End If Else If (rB < rG) Then Minimum = rB Else Minimum = rG End If End If End Function
'RGB转换为色相(h)、饱和度(s)、亮度(l)
Public Sub RGBToHLS( _
ByVal r As Long, ByVal g As Long, ByVal b As Long, _
h As Single, s As Single, l As Single)
Dim Max As Single
Dim Min As Single
Dim delta As Single
Dim rR As Single, rG As Single, rB As Single rR = r / 255: rG = g / 255: rB = b / 255
Max = Maximum(rR, rG, rB)
Min = Minimum(rR, rG, rB)
l = (Max + Min) / 2 '{This is the lightness}
'{Next calculate saturation}
If Max = Min Then
'begin {Acrhomatic case}
s = 0
h = 0
'end {Acrhomatic case}
Else
'begin {Chromatic case}
'{First calculate the saturation.}
If l <= 0.5 Then
s = (Max - Min) / (Max + Min)
Else
s = (Max - Min) / (2 - Max - Min)
End If
'{Next calculate the hue.}
delta = Max - Min
If rR = Max Then
h = (rG - rB) / delta '{Resulting color is between yellow and magenta}
ElseIf rG = Max Then
h = 2 + (rB - rR) / delta '{Resulting color is between cyan and yellow}
ElseIf rB = Max Then
h = 4 + (rR - rG) / delta '{Resulting color is between magenta and cyan}
End If
End If
End Sub'色相(h)、饱和度(s)、亮度(l)转换为RGB
Public Sub HLSToRGB( _
ByVal h As Single, ByVal s As Single, ByVal l As Single, _
r As Long, g As Long, b As Long)
Dim rR As Single, rG As Single, rB As Single
Dim Min As Single, Max As Single If s = 0 Then
' Achromatic case:
rR = l: rG = l: rB = l
Else
' Chromatic case:
' delta = Max-Min
If l <= 0.5 Then
's = (Max - Min) / (Max + Min)
' Get Min value:
Min = l * (1 - s)
Else
's = (Max - Min) / (2 - Max - Min)
' Get Min value:
Min = l - s * (1 - l)
End If
' Get the Max value:
Max = 2 * l - Min
' Now depending on sector we can evaluate the h,l,s:
If (h < 1) Then
rR = Max
If (h < 0) Then
rG = Min
rB = rG - h * (Max - Min)
Else
rB = Min
rG = h * (Max - Min) + rB
End If
ElseIf (h < 3) Then
rG = Max
If (h < 2) Then
rB = Min
rR = rB - (h - 2) * (Max - Min)
Else
rR = Min
rB = (h - 2) * (Max - Min) + rR
End If
Else
rB = Max
If (h < 4) Then
rR = Min
rG = rR - (h - 4) * (Max - Min)
Else
rG = Min
rR = (h - 4) * (Max - Min) + rG
End If
End If
End If
r = rR * 255: g = rG * 255: b = rB * 255
End SubPrivate Function Maximum(rR As Single, rG As Single, rB As Single) As Single
If (rR > rG) Then
If (rR > rB) Then
Maximum = rR
Else
Maximum = rB
End If
Else
If (rB > rG) Then
Maximum = rB
Else
Maximum = rG
End If
End If
End FunctionPrivate Function Minimum(rR As Single, rG As Single, rB As Single) As Single
If (rR < rG) Then
If (rR < rB) Then
Minimum = rR
Else
Minimum = rB
End If
Else
If (rB < rG) Then
Minimum = rB
Else
Minimum = rG
End If
End If
End Function
即:(R+G+B)/3=灰度色,也可以理解为亮度大小,0为最暗,255为最亮
根据这个原理,灰度色小于200的值你就累计加一就可以了。
灰度 = (R*299 + G*587 + B*114 + 500) / 1000
变种:
灰度 = (R*30 + G*59 + B*11 + 50) / 100从代码可以看出l = (Max + Min) / 2,亮度应该是R,G,B三个数值中的(最大值+最小值)/2
如果你不在乎速度的话,可以使用GetPixel(或VB中的Point方法,更慢)。如果你要求速度的话,可以用CreateDIBSection、GetDIBits等,比前面的要快上百倍。具体这些函数的使用可以查阅MSDN中GDI有关章节。
PS:亮度的确和灰度不是一回事。亮度的RGB三个分量有加权值的,不是简单的平均数。
Y(亮度)=(0.299*R)+(0.587*G)+(0.114*B)