Zum Hauptinhalt springen

Beispiel - HLS-Farbwerte

Beispiel - HLS-Farbwerte Umrechnung von Farbwerten in das HLS-Modell

In diesem Beispiel wird die Umrechnung von Farbmodellen vorgestellt. Die in CONZEPT 16 verwendeten Farbkonstanten beziehen sich immer auf das RGB-Farbmodell. In diesem Modell wird jede Farbe auf einer Mischung der Farben Rot, Grün und Blau erzeugt. Die jeweiligen Anteile werden durch Farbwerte im Bereich [0..255] angegeben.

Bei Variablen vom Typ color kann über die entsprechenden Eigenschaften der Anteil einer Farbe ermittelt werden. Die Defines mUndefined, mValue2Float und mFloat2Value werden in diesem Text erläutert.

Der vollständige Prozedurtext ohne die erklärenden Kommentare kann hier eingesehen werden.

define
{
mUndefined : -1.0
mValue2Float(a) : CnvFI(a) / 255.0
mFloat2Value(a) : CnvIF(a * 255.0)
}

Die meisten Algorithmen zur Umrechnung in andere Farbmodelle basieren auf der Angabe der Farbanteile im Bereich [0..1]. Zur Umrechnung können die Defines mValue2Float (Umrechnung von [0..255] in [0..1]) und mFloat2Value (Umrechnung von [0..1] in [0..255]) verwendet werden.

In diesem Beispiel erfolgt die Umrechnung in das Farbmodell HLS. Dieses Modell besteht ebenfalls aus drei Werten. Der erste Wert bestimmt die Farbe (Hue), der zweite die Helligkeit (Lumination) und der dritte die Sättigung (Saturation). Im Falle das keine Farbe, sondern ein Graustufenwert angegeben werden soll, wird als Farbe der Wert mUndefined angegeben.

Die Umrechnung von RGB-Werten in HLS-Werten erfolgt durch die Funktion Rgb2Hls(). Als Parameter werden zwei Arrays übergeben. Jedes Array besteht aus drei float-Werten. Im ersten Array werden die in [0..1] Werte umgerechneten RGB-Farbanteile übergeben. Als Ergebnis stehen nach der Ausführung der Funktion die HLS-Werte in dem zweiten Array.

sub Rgb2Hls
(
var aRgbColor : float[]; // in: Farbwerte in RGB-Darstellung
var aHlsColor : float[]; // out: Farbwerte in HLS-Darstellung
)

local
{
tMax : float;
tMin : float;
tDelta : float;
}

{
tMax # Max(aRgbColor[1], Max(aRgbColor[2], aRgbColor[3]));
tMin # Min(aRgbColor[1], Min(aRgbColor[2], aRgbColor[3]));
aHlsColor[2] # (tMax + tMin) / 2.0; // Helligkeit

if (tMax = tMin)
{
// Berechnung der Farbe und der Sättigung für s/w Darstellung
aHlsColor[1] # mUndefined;
aHlsColor[3] # 0.0;
}
else
{
// Berechnung der Sättigung für Farbdarstellung
if (aHlsColor[2] <= 0.5)
aHlsColor[3] # (tMax - tMin) / (tMax + tMin);
else
aHlsColor[3] # (tMax - tMin) / (2.0 - tMax - tMin);

// Berechnung der Farbe für Farbdarstellung
tDelta # tMax - tMin;
switch (true)
{
case (aRgbColor[1] = tMax) : aHlsColor[1] # (aRgbColor[2] - aRgbColor[3]) / tDelta;
case (aRgbColor[2] = tMax) : aHlsColor[1] # 2.0 + (aRgbColor[3] - aRgbColor[1]) / tDelta;
case (aRgbColor[3] = tMax) : aHlsColor[1] # 4.0 + (aRgbColor[1] - aRgbColor[2]) / tDelta;
}

aHlsColor[1] # aHlsColor[1] * 60.0;
if (aHlsColor[1] < 0.0)
aHlsColor[1] # aHlsColor[1] + 360.0;
}
}

Bei der HLS-Darstellung steht in der Komponente Hue ein Winkel, der die Farbe angibt. Hier können also Werte von [0..360] Grad stehen. Die Werte für Helligkeit (L) und Sättigung (S) liegen im Bereich [0..1].

Die Funktion Value() wird zur Umrechnung in RGB-Werte benötigt.

sub Value
(
an1 : float;
an2 : float;
ahue : float;
) : float;

{
// Wertebereich überprüfen und angleichen
if (ahue > 360.0)
ahue # ahue - 360.0;
if (ahue < 0.0)
ahue # ahue + 360.0;

// Farbwert berechnen
switch (true)
{
case (ahue < 60.0) : return(an1 + (an2 - an1) * ahue / 60.0);
case (ahue < 180.0) : return(an2);
case (ahue < 240.0) : return(an1 + (an2 - an1) * (240.0 - ahue) / 60.0);
default : return(an1);
}
}

Die Funktion Hls2Rgb() berechnet aus den HLS-Werten die entsprechenden RGB-Werte. Als Parameter werden zwei Arrays übergeben. Jedes Array besteht aus drei float-Werten. Im ersten Array werden die HLS-Werte übergeben. Als Ergebnis stehen nach der Ausführung der Funktion die RGB-Werte in dem zweiten Array. Die RGB-Werte müssen noch mit dem Define mFloat2Value in den Wertebereich [0..255] transformiert werden, bevor sie mit ColorRgbMake () zu einer Farb-Konstanten zusammengesetzt werden können.

sub Hls2Rgb
(
var aHlsColor : float[]; // in: Farbwerte in HLS-Darstellung
var aRgbColor : float[]; // out: Farbwerte in RGB-Darstellung
)

local
{
tm1 : float;
tm2 : float;
}

{
if (aHlsColor[2] <= 0.5)
tm2 # aHlsColor[2] * (1.0 + aHlsColor[3]);
else
tm2 # aHlsColor[2] + aHlsColor[3] - (aHlsColor[2] * aHlsColor[3]);
tm1 # (2.0 * aHlsColor[2]) - tm2;
if (aHlsColor[3] = 0.0)
{
if (aHlsColor[1] = mUndefined)
{
// s/w Darstellung
aRgbColor[1] # aHlsColor[2];
aRgbColor[2] # aHlsColor[2];
aRgbColor[3] # aHlsColor[2];
}
}
else
{
// Farb-Darstellung
aRgbColor[1] # Value(tm1, tm2, aHlsColor[1] + 120.0);
aRgbColor[2] # Value(tm1, tm2, aHlsColor[1]);
aRgbColor[3] # Value(tm1, tm2, aHlsColor[1] - 120.0);
}
}

Mit diesen Funktionen kann auf einfache Weise die Helligkeit von Farben verändert werden:

...
tColor->vpColorSystem # aEvt:Obj->wpColBkg;
tRgbColor[1] # Value2Float(tColor->vpColorR);
tRgbColor[2] # Value2Float(tColor->vpColorG);
tRgbColor[3] # Value2Float(tColor->vpColorB);
Rgb2Hls(var tRgbColor, var tHlsColor);
tHlsColor[2] # tHlsColor[2] + 0.001;
Hls2Rgb(var tHlsColor, var tRgbColor);
aEvt:Obj->wpColBkg # ColorRgbMake(mFloat2Value(tRgbColor[1]), mFloat2Value(tRgbColor[2]), mFloat2Value(tRgbColor[3]));
...