HSL<->RGB Konverter

Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Neue Antwort erstellen

DaysShadow

Betreff: HSL<->RGB Konverter

BeitragSo, Jul 19, 2009 19:24
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich habe mich die letzten Tage mit RGB und HSL beschäftigt, dabei ist dann das heraus gekommen.

BlitzMax: [AUSKLAPPEN]
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

'Calculate Max(R, G, B)

If g > rgbMax rgbMax = g

If b > rgbMax rgbMax = b


'Calculate Min(R, G, B)

If g < rgbMin rgbMin = g

If b < rgbMin rgbMin = b

'Calculate _hue

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

'Calculate _lightness(we need it first because _saturation calculation needs it)

_lightness = 0.5 * (rgbMax + rgbMin)

'Calculate _saturation

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

'Calculate Ints or percentages

_huei = Int(_hue)
_saturationi = Int(_saturation * 100)
_lightnessi = Int(_lightness * 100)

EndFunction

Function ConvertHSLtoRGB(rvar:Int Var, gvar:Int Var, bvar:Int Var)

'Needed variables...
Local q:Float, p:Float, hk:Float, tr:Float, tg:Float, tb:Float
Local r:Float, g:Float, b:Float

'Calculate q

If _lightness < 0.5 q = _lightness * (1.0 + _saturation)

If _lightness >= 0.5 q = _lightness + _saturation - (_lightness * _saturation)

'Calculate p

p = (2.0 * _lightness) - q

'Calculate hk

hk = _hue / 360.0

'Calculate tr, tg, tb

tr = hk + (1.0 / 3.0)

tg = hk

tb = hk - (1.0 / 3.0)

'Check tr, tg and tb are between 0 and 1 else add or sub 1 so that the condition is fulfilled

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

'Calculate r,g and b

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:
user posted image

Download mit Beispiel und Bild des Fliegers:
https://www.blitzforum.de/upload/file.php?id=6293

Vielleicht kann es ja jemand gebrauchen Wink
In selber Form habe ich auch einen HSV<->RGB Konverter geschrieben, aber HSL erachte ich als sinnvoller.
Wenn Bedarf besteht einfach melden... Wink

Werde vielleicht auch noch jeweils einen ColorPicker für die Bar und den Circle machen.

MfG DaysShadow
Blessed is the mind too small for doubt

Holzchopf

Meisterpacker

BeitragSo, Jul 19, 2009 19:43
Antworten mit Zitat
Benutzer-Profile anzeigen
Hihi. Und ich wollte mich tatsächlich die Tage mal dran setzen, meine eigenen solchen Funktionen mal in BMax umzuschreiben und als Modul rauszubringen Rolling Eyes
Frag dich also nicht, wenn bald was ähnliches im Module-Forum auftaucht =)
Erledige alles Schritt um Schritt - erledige alles. - Holzchopf
CC BYBinaryBorn - Yogurt ♫ (31.10.2018)
Im Kopf da knackt's und knistert's sturm - 's ist kein Gedanke, nur ein Wurm

DaysShadow

BeitragSo, Jul 19, 2009 19:43
Antworten mit Zitat
Benutzer-Profile anzeigen
Nicht schlimm, mir dient es ja zum lernen Wink
Blessed is the mind too small for doubt

hazumu-kun

BeitragMo, Jul 20, 2009 14:53
Antworten mit Zitat
Benutzer-Profile anzeigen
@ Holzchopf

Schlimm wenn ich deine Funktionen für BPlus en bissel abgeändert hab und den author-header entfernt hab?
Bleibt ja für den privaten Gebrauch von mir. willst du en credits Eintrag wenn ich deine Funktionen in nem Release benutze?
Warum kann es keine omnipotente Macht geben?
Weil diese omnipotente Macht in der Lage sein müsste, einen so schweren Stein zu schaffen, dass sie ihn nicht heben kann
-> nicht omnipotent

DaysShadow

BeitragMo, Jul 20, 2009 15:07
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich finde eine Erwähnung wäre das mindeste oder?

btw hättest du ihm das auch per PM schicken können...
Blessed is the mind too small for doubt

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group