Ich habe mich die letzten Tage mit RGB und HSL beschäftigt, dabei ist dann das heraus gekommen.
BlitzMax: [AUSKLAPPEN] [EINKLAPPEN] Type TColorSpaceHSL Global _hue:Float Global _saturation:Float Global _lightness:Float Global _huei:Int Global _saturationi:Int Global _lightnessi:Int Global _colorBar:TImage = Null Global _colorCircle:TImage = Null
Function ConvertRGBtoHSL(r:Float, g:Float, b:Float) If r > 1 r:/ 255.0 If g > 1 g:/ 255.0 If b > 1 b:/ 255.0 Local rgbMax:Float = r Local rgbMin:Float = r If g > rgbMax rgbMax = g If b > rgbMax rgbMax = b
If g < rgbMin rgbMin = g If b < rgbMin rgbMin = b If rgbMax = rgbMin _hue = 0 ElseIf rgbMax = r _hue = 60 * (0 + ( (g - b) / (rgbMax - rgbMin) ) ) ElseIf rgbMax = g _hue = 60 * (2 + ( (b - r) / (rgbMax - rgbMin) ) ) ElseIf rgbMax = b _hue = 60 * (4 + ( (r - g) / (rgbMax - rgbMin) ) ) EndIf If _hue < 0 _hue:+ 360 _lightness = 0.5 * (rgbMax + rgbMin) If rgbMax = rgbMin _saturation = 0 ElseIf _lightness <= 0.5 _saturation = (rgbMax - rgbMin) / (2 * _lightness) ElseIf _lightness > 0.5 _saturation = (rgbMax - rgbMin) / (2 - (2 * _lightness) ) EndIf _huei = Int(_hue) _saturationi = Int(_saturation * 100) _lightnessi = Int(_lightness * 100) EndFunction Function ConvertHSLtoRGB(rvar:Int Var, gvar:Int Var, bvar:Int Var) Local q:Float, p:Float, hk:Float, tr:Float, tg:Float, tb:Float Local r:Float, g:Float, b:Float If _lightness < 0.5 q = _lightness * (1.0 + _saturation) If _lightness >= 0.5 q = _lightness + _saturation - (_lightness * _saturation) p = (2.0 * _lightness) - q hk = _hue / 360.0 tr = hk + (1.0 / 3.0) tg = hk tb = hk - (1.0 / 3.0) If tr > 1.0 tr:- 1.0 If tr < 0 tr:+ 1.0 If tg > 1.0 tg:- 1.0 If tg < 0 tg:+ 1.0 If tb > 1.0 tb:- 1.0 If tb < 0 tb:+ 1.0 CalculateRGB(r, q, p, tr) CalculateRGB(g, q, p, tg) CalculateRGB(b, q, p, tb) rvar = Int(r * 255.0) gvar = Int(g * 255.0) bvar = Int(b * 255.0) EndFunction Function CalculateRGB(cvar:Float Var, q:Float, p:Float, tc:Float) If tc < (1.0 / 6.0) cvar = p + ( (q - p) * 6.0 * tc) EndIf If tc >= (1.0 / 6.0) And tc < 0.5 cvar = q EndIf If tc >= 0.5 And tc < (2.0 / 3.0) cvar = p + ( (q - p) * 6.0 * ( (2.0 / 3.0) - tc) ) EndIf If tc >= (2.0 / 3.0) cvar = p EndIf
EndFunction Function ColorImage:TPixmap(Pixmap:TPixmap, hueChange:Float, saturationChange:Float, lightnessChange:Float) Local argb:Int, a:Int, r:Int, g:Int, b:Int For Local y:Int = 0 To Pixmap.height - 1 For Local x:Int = 0 To Pixmap.width - 1 argb = Pixmap.ReadPixel(x, y) a = argb Shr 24 ConvertRGBtoHSL( (argb Shr 16) & $FF, (argb Shr 8) & $FF, (argb & $FF) ) _hue:+ hueChange If _hue < 0 _hue:+ 360 ElseIf _hue > 359 _hue:- 360 EndIf _saturation:+ saturationChange If _saturation < 0 _saturation = 0 ElseIf _saturation > 1 _saturation = 1 EndIf _lightness:+ lightnessChange If _lightness < 0 _lightness = 0 ElseIf _lightness > 1 _lightness = 1 EndIf ConvertHSLtoRGB(r, g, b) argb = 0 argb = a Shl 24 + r Shl 16 + g Shl 8 + b Pixmap.WritePixel(x, y, argb) Next Next Return Pixmap EndFunction Function ColorCertainHue:TPixmap(Pixmap:TPixmap, certainHue:Int, newHue:Int) Local argb:Int, a:Int, r:Int, g:Int, b:Int For Local y:Int = 0 To Pixmap.height - 1 For Local x:Int = 0 To Pixmap.width - 1 argb = Pixmap.ReadPixel(x, y) a = argb Shr 24 ConvertRGBtoHSL( (argb Shr 16) & $FF, (argb Shr 8) & $FF, (argb & $FF) ) If _huei = certainHue _hue = Float(newHue) ConvertHSLtoRGB(r, g, b) argb = 0 argb = a Shl 24 + r Shl 16 + g Shl 8 + b Pixmap.WritePixel(x, y, argb) Next Next Return Pixmap EndFunction Function DrawColorBar(x:Float, y:Float) DrawImage _colorBar, x, y EndFunction Function DrawColorCircle(x:Float, y:Float) DrawImage _colorCircle, x, y EndFunction Function MakeColorBar(height:Float) Local Pixmap:TPixmap = CreatePixmap(360, height, PF_BGRA8888) Local hueTmp:Float = _hue, saturationTmp:Float = _saturation, lightnessTmp:Float = _lightness Local r:Int, g:Int, b:Int Local index:Float = 0, heightProgress:Float = 0 Pixmap.ClearPixels($00000000) _saturation = 1.0 Repeat _hue = index Repeat _lightness = heightProgress / height ConvertHSLtoRGB(r, g, b) Pixmap.WritePixel(index, heightProgress, $FF Shl 24 + r Shl 16 + g Shl 8 + b) heightProgress:+ 1 Until heightProgress > height - 1 heightProgress = 0 index:+ 1 Until index > 359 _colorBar = LoadImage(Pixmap) _hue = hueTmp _saturation = saturationTmp _lightness = lightnessTmp EndFunction Function MakeColorCircle(radius:Float)
Local Pixmap:TPixmap = CreatePixmap(radius * 2, radius * 2, PF_BGRA8888) Local hueTmp:Float = _hue, saturationTmp:Float = _saturation, lightnessTmp:Float = _lightness Local r:Int, g:Int, b:Int Local index:Float = 0, radiusProgress:Float = 0, progressStep:Float = 100 / radius / 2 Pixmap.ClearPixels($00000000) _saturation = 1.0 Repeat _hue = index Repeat _lightness = radiusProgress / radius ConvertHSLtoRGB(r, g, b) Pixmap.WritePixel( radius + (radiusProgress * Cos(index - 90) ), radius + (radiusProgress * Sin(index - 90)), $FF Shl 24 + r Shl 16 + g Shl 8 + b ) radiusProgress:+ progressStep Until radiusProgress > radius - 1 radiusProgress = 0 index:+ progressStep Until index > 360 _colorCircle = LoadImage(Pixmap) _hue = hueTmp _saturation = saturationTmp _lightness = lightnessTmp
EndFunction Function ResetHSL() _hue = 0 _huei = 0 _saturation = 0 _saturationi = 0 _lightness = 0 _lightnessi = 0 EndFunction Function SetHSL(h:Float, s:Float, l:Float) _hue = h _huei = Int(h) _saturation = s _saturationi = Int(s * 100) _lightness = l _lightnessi = Int(l * 100) EndFunction
EndType
Ein HSL<->RGB Konverter der auch zwei Funktionen hat um Bilder einzufärben, sowie eine ColorBar und einen ColorCircle die in jeweils eins dem Type zugehörigen Image gezeichnet werden.
Bild mit Bar und Circle und zwei Einfärbebeispielen:
Download mit Beispiel und Bild des Fliegers:
https://www.blitzforum.de/upload/file.php?id=6293
Vielleicht kann es ja jemand gebrauchen
In selber Form habe ich auch einen HSV<->RGB Konverter geschrieben, aber HSL erachte ich als sinnvoller.
Wenn Bedarf besteht einfach melden...
Werde vielleicht auch noch jeweils einen ColorPicker für die Bar und den Circle machen.
MfG DaysShadow
|