Für ein kleines Projekt will ich eine Liste mit Farben in einer Liste darstellen, habe aber gemerkt, dass die Darstellung nicht optimal ist.
Ideal wäre eine Darstellung der Farben so sortiert / gruppiert, dass sie einen idealen Übergang haben.
Was ich bis jetzt implementiert habe:
AutoIt
;Coded by UEZ build 2023-03-14
#include <Array.au3>
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
_GDIPlus_Startup()
Global $hGUI = GUICreate("GDI+ Color Sorting / Grouping Test", 800, 300)
GUISetState()
Global $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)
Global $hPen = _GDIPlus_PenCreate(0)
_GDIPlus_GraphicsClear($hGraphic)
Global $aColortable[511], $i, $y = 0
For $i = 0 To UBound($aColortable) - 1
$aColortable[$i] = Int(Random() * 0xFFFFFF)
Next
DrawColors($y, "Random")
SortByDistance($aColortable)
$y += 40
DrawColors($y, "Distance")
SortByHSL($aColortable)
$y += 40
DrawColors($y, "HSL")
SortByHSV($aColortable)
$y += 40
DrawColors($y, "HSV")
SortByGroupingHSL($aColortable)
$y += 40
DrawColors($y, "Grouping HSL")
SortByGroupingHSV($aColortable)
$y += 40
DrawColors($y, "Grouping HSV")
_ArraySort($aColortable)
$y += 40
DrawColors($y, "Default Array Sort")
While GUIGetMsg() <> $GUI_EVENT_CLOSE
Sleep(10)
WEnd
_GDIPlus_PenDispose($hPen)
_GDIPlus_GraphicsDispose($hGraphic)
_GDIPlus_Shutdown()
GUIDelete()
Exit
Func DrawColors($y, $txt = 0)
For $i = 0 To UBound($aColortable) - 1
_GDIPlus_PenSetColor($hPen, BitOR(0xFF000000, $aColortable[$i]))
_GDIPlus_GraphicsDrawLine($hGraphic, $i, $y, $i, $y + 32, $hPen)
Next
If $txt Then _GDIPlus_GraphicsDrawString($hGraphic, $txt, $i + 8, $y + 4, "Arial", 16, Default, 0xFFFFFFFF)
EndFunc
Func SortByDistance(ByRef $aColortable)
Local $i, $aTmp[2], $swapped
Do ;bubblesort -> slow!
$swapped = 0
For $i = 0 To UBound($aColortable) - 2
Distance($aColortable[$i], $aColortable[$i + 1])
If @extended Then
$aTmp[0] = $aColortable[$i]
$aColortable[$i] = $aColortable[$i + 1]
$aColortable[$i + 1] = $aTmp[0]
$swapped = 1
EndIf
Next
Until $swapped = 0
EndFunc
Func SortByHSL(ByRef $aColortable, $sc = 1)
Local $aColortable2[UBound($aColortable)][4]
Local $a, $i
For $i = 0 To UBound($aColortable) - 1
$a = RGB2HSL($aColortable[$i])
$aColortable2[$i][0] = $aColortable[$i]
$aColortable2[$i][1] = $a[0]
$aColortable2[$i][2] = $a[1]
$aColortable2[$i][3] = $a[2]
Next
$sc = Max(Min($sc, 3), 1)
_ArraySort($aColortable2, 0, 0, 0, $sc)
For $i = 0 To UBound($aColortable2) - 1
$aColortable[$i] = $aColortable2[$i][0]
Next
Dim $aColortable2[0]
EndFunc
Func SortByHSV(ByRef $aColortable, $sc = 1)
Local $aColortable2[UBound($aColortable)][4]
Local $a, $i
For $i = 0 To UBound($aColortable) - 1
$a = RGB2HSV($aColortable[$i])
$aColortable2[$i][0] = $aColortable[$i]
$aColortable2[$i][1] = $a[0]
$aColortable2[$i][2] = $a[1]
$aColortable2[$i][3] = $a[2]
Next
$sc = Max(Min($sc, 3), 1)
_ArraySort($aColortable2, 0, 0, 0, $sc)
For $i = 0 To UBound($aColortable2) - 1
$aColortable[$i] = $aColortable2[$i][0]
Next
Dim $aColortable2[0]
EndFunc
Func SortByGroupingHSL(ByRef $aColortable, $sc = 2)
Local $red[0][2], $orange[0][2], $yellow[0][2], $lime[0][2], $green[0][2], $turqoise[0][2], $cyan[0][2], $cobalt[0][2], $blue[0][2], $violet[0][2], $magenta[0][2], $crimson[0][2], $grey[0][2], $i, $j, $col
$sc = Max(Min($sc, 2), 0)
For $i = 0 To UBound($aColortable) - 1
$col = $aColortable[$i]
Switch RGBtoColorGroup($col)
Case "red"
_ArrayAdd($red, $aColortable[$i] & "|" & RGB2HSL($col)[$sc])
Case "orange"
_ArrayAdd($orange, $aColortable[$i] & "|" & RGB2HSL($col)[$sc])
Case "yellow"
_ArrayAdd($yellow, $aColortable[$i] & "|" & RGB2HSL($col)[$sc])
Case "lime"
_ArrayAdd($lime, $aColortable[$i] & "|" & RGB2HSL($col)[$sc])
Case "green"
_ArrayAdd($green, $aColortable[$i] & "|" & RGB2HSL($col)[$sc])
Case "turqoise"
_ArrayAdd($turqoise, $aColortable[$i] & "|" & RGB2HSL($col)[$sc])
Case "cyan"
_ArrayAdd($cyan, $aColortable[$i] & "|" & RGB2HSL($col)[$sc])
Case "cobalt"
_ArrayAdd($cobalt, $aColortable[$i] & "|" & RGB2HSL($col)[$sc])
Case "blue"
_ArrayAdd($blue, $aColortable[$i] & "|" & RGB2HSL($col)[$sc])
Case "violet"
_ArrayAdd($violet, $aColortable[$i] & "|" & RGB2HSL($col)[$sc])
Case "magenta"
_ArrayAdd($magenta, $aColortable[$i] & "|" & RGB2HSL($col)[$sc])
Case "crimson"
_ArrayAdd($crimson, $aColortable[$i] & "|" & RGB2HSL($col)[$sc])
Case "grey"
_ArrayAdd($grey, $aColortable[$i] & "|" & RGB2HSL($col)[$sc])
EndSwitch
Next
_ArraySort($red, 0, 0, 0, 1)
_ArraySort($orange, 0, 0, 0, 1)
_ArraySort($yellow, 0, 0, 0, 1)
_ArraySort($lime, 0, 0, 0, 1)
_ArraySort($green, 0, 0, 0, 1)
_ArraySort($turqoise, 0, 0, 0, 1)
_ArraySort($cyan, 0, 0, 0, 1)
_ArraySort($cobalt, 0, 0, 0, 1)
_ArraySort($blue, 0, 0, 0, 1)
_ArraySort($violet, 0, 0, 0, 1)
_ArraySort($magenta, 0, 0, 0, 1)
_ArraySort($crimson, 0, 0, 0, 1)
_ArraySort($grey, 0, 0, 0, 1)
$i = 0
For $j = 0 To UBound($red) - 1
$aColortable[$i] = $red[$j][0]
$i += 1
Next
For $j = 0 To UBound($orange) - 1
$aColortable[$i] = $orange[$j][0]
$i += 1
Next
For $j = 0 To UBound($yellow) - 1
$aColortable[$i] = $yellow[$j][0]
$i += 1
Next
For $j = 0 To UBound($lime) - 1
$aColortable[$i] = $lime[$j][0]
$i += 1
Next
For $j = 0 To UBound($green) - 1
$aColortable[$i] = $green[$j][0]
$i += 1
Next
For $j = 0 To UBound($turqoise) - 1
$aColortable[$i] = $turqoise[$j][0]
$i += 1
Next
For $j = 0 To UBound($cyan) - 1
$aColortable[$i] = $cyan[$j][0]
$i += 1
Next
For $j = 0 To UBound($cobalt) - 1
$aColortable[$i] = $cobalt[$j][0]
$i += 1
Next
For $j = 0 To UBound($blue) - 1
$aColortable[$i] = $blue[$j][0]
$i += 1
Next
For $j = 0 To UBound($violet) - 1
$aColortable[$i] = $violet[$j][0]
$i += 1
Next
For $j = 0 To UBound($magenta) - 1
$aColortable[$i] = $magenta[$j][0]
$i += 1
Next
For $j = 0 To UBound($crimson) - 1
$aColortable[$i] = $crimson[$j][0]
$i += 1
Next
For $j = 0 To UBound($grey) - 1
$aColortable[$i] = $grey[$j][0]
$i += 1
Next
EndFunc
Func SortByGroupingHSV(ByRef $aColortable, $sc = 2)
Local $red[0][2], $orange[0][2], $yellow[0][2], $lime[0][2], $green[0][2], $turqoise[0][2], $cyan[0][2], $cobalt[0][2], $blue[0][2], $violet[0][2], $magenta[0][2], $crimson[0][2], $grey[0][2], $i, $j, $col
$sc = Max(Min($sc, 2), 0)
For $i = 0 To UBound($aColortable) - 1
$col = $aColortable[$i]
Switch RGBtoColorGroup($col)
Case "red"
_ArrayAdd($red, $aColortable[$i] & "|" & RGB2HSV($col)[$sc])
Case "orange"
_ArrayAdd($orange, $aColortable[$i] & "|" & RGB2HSV($col)[$sc])
Case "yellow"
_ArrayAdd($yellow, $aColortable[$i] & "|" & RGB2HSV($col)[$sc])
Case "lime"
_ArrayAdd($lime, $aColortable[$i] & "|" & RGB2HSV($col)[$sc])
Case "green"
_ArrayAdd($green, $aColortable[$i] & "|" & RGB2HSV($col)[$sc])
Case "turqoise"
_ArrayAdd($turqoise, $aColortable[$i] & "|" & RGB2HSV($col)[$sc])
Case "cyan"
_ArrayAdd($cyan, $aColortable[$i] & "|" & RGB2HSV($col)[$sc])
Case "cobalt"
_ArrayAdd($cobalt, $aColortable[$i] & "|" & RGB2HSV($col)[$sc])
Case "blue"
_ArrayAdd($blue, $aColortable[$i] & "|" & RGB2HSV($col)[$sc])
Case "violet"
_ArrayAdd($violet, $aColortable[$i] & "|" & RGB2HSV($col)[$sc])
Case "magenta"
_ArrayAdd($magenta, $aColortable[$i] & "|" & RGB2HSV($col)[$sc])
Case "crimson"
_ArrayAdd($crimson, $aColortable[$i] & "|" & RGB2HSV($col)[$sc])
Case "grey"
_ArrayAdd($grey, $aColortable[$i] & "|" & RGB2HSV($col)[$sc])
EndSwitch
Next
_ArraySort($red, 0, 0, 0, 1)
_ArraySort($orange, 0, 0, 0, 1)
_ArraySort($yellow, 0, 0, 0, 1)
_ArraySort($lime, 0, 0, 0, 1)
_ArraySort($green, 0, 0, 0, 1)
_ArraySort($turqoise, 0, 0, 0, 1)
_ArraySort($cyan, 0, 0, 0, 1)
_ArraySort($cobalt, 0, 0, 0, 1)
_ArraySort($blue, 0, 0, 0, 1)
_ArraySort($violet, 0, 0, 0, 1)
_ArraySort($magenta, 0, 0, 0, 1)
_ArraySort($crimson, 0, 0, 0, 1)
_ArraySort($grey, 0, 0, 0, 1)
$i = 0
For $j = 0 To UBound($red) - 1
$aColortable[$i] = $red[$j][0]
$i += 1
Next
For $j = 0 To UBound($orange) - 1
$aColortable[$i] = $orange[$j][0]
$i += 1
Next
For $j = 0 To UBound($yellow) - 1
$aColortable[$i] = $yellow[$j][0]
$i += 1
Next
For $j = 0 To UBound($lime) - 1
$aColortable[$i] = $lime[$j][0]
$i += 1
Next
For $j = 0 To UBound($green) - 1
$aColortable[$i] = $green[$j][0]
$i += 1
Next
For $j = 0 To UBound($turqoise) - 1
$aColortable[$i] = $turqoise[$j][0]
$i += 1
Next
For $j = 0 To UBound($cyan) - 1
$aColortable[$i] = $cyan[$j][0]
$i += 1
Next
For $j = 0 To UBound($cobalt) - 1
$aColortable[$i] = $cobalt[$j][0]
$i += 1
Next
For $j = 0 To UBound($blue) - 1
$aColortable[$i] = $blue[$j][0]
$i += 1
Next
For $j = 0 To UBound($violet) - 1
$aColortable[$i] = $violet[$j][0]
$i += 1
Next
For $j = 0 To UBound($magenta) - 1
$aColortable[$i] = $magenta[$j][0]
$i += 1
Next
For $j = 0 To UBound($crimson) - 1
$aColortable[$i] = $crimson[$j][0]
$i += 1
Next
For $j = 0 To UBound($grey) - 1
$aColortable[$i] = $grey[$j][0]
$i += 1
Next
EndFunc
Func RGBtoColorGroup($iColor)
Local $HSL = RGB2HSL($iColor), $H, $r
If $HSL[0] = 0 And $HSL[1] = 0 Then
$H = -1
Else
$H = $HSL[0]
EndIf
Switch $H
Case 0 To 15, 345 To 360
Return "red"
Case 15 To 45
Return "orange"
Case 45 To 75
Return "yellow"
Case 75 To 105
Return "lime"
Case 105 To 135
Return "green"
Case 135 To 165
Return "turqoise"
Case 165 To 195
Return "cyan"
Case 195 To 225
Return "cobalt"
Case 225 To 255
Return "blue"
Case 255 To 285
Return "violet"
Case 285 To 315
Return "magenta"
Case 315 To 345
Return "crimson"
Case -1
Return "grey"
EndSwitch
EndFunc
Func Distance($c1, $c2)
Local $r1 = BitShift(BitAND($c1, 0xFF0000), 16), $g1 = BitShift(BitAND($c1, 0xFF00), 8), $b1 = BitAND($c1, 0xFF)
Local $r2 = BitShift(BitAND($c2, 0xFF0000), 16), $g2 = BitShift(BitAND($c2, 0xFF00), 8), $b2 = BitAND($c2, 0xFF)
Local $dr = $r2 - $r1, $dg = $g2 - $g1, $db = $b2 - $b1
Return SetExtended($dr + $dg + $db < 0, Sqrt($dr * $dr + $dg * $dg + $db * $db))
EndFunc
Func RGB2HSL($iColor)
Local $r = BitAND(BitShift($iColor, 16), 255) / 255, $g = BitAND(BitShift($iColor, 8), 255) / 255, $b = BitAND($iColor, 255) / 255
Local $Cmax = Max(Max($r, $g), $b), $Cmin = Min(Min($r, $g), $b), $deltaChroma = $Cmax - $Cmin
Local $L = ($Cmin + $Cmax) / 2, $H, $S
If $deltaChroma = 0 Then
$H = 0
$S = 0
Else
$S = $deltaChroma / (1 - Abs(2 * $L - 1))
Switch $Cmax
Case $r
$H = Mod(($g - $b) / $deltaChroma, 6)
Case $g
$H = ($b - $r) / $deltaChroma + 2
Case Else
$H = ($r - $g) / $deltaChroma + 4
EndSwitch
$H *= 60
If $H < 0 Then $H += 360
EndIf
Local $aHSL[3] = [$H, $S, $L]
Return $aHSL
EndFunc
Func RGB2HSV($iColor)
Local $r = BitAND(BitShift($iColor, 16), 255) / 255, $g = BitAND(BitShift($iColor, 8), 255) / 255, $b = BitAND($iColor, 255) / 255
Local $h, $s, $v, $c, $minRGB, $maxRGB, $deltaRGB
$minRGB = Min3($r, $g, $b)
$maxRGB = Max3($r, $g, $b)
$deltaRGB = $maxRGB - $minRGB
If $deltaRGB = 0 Then
$h = 0
ElseIf $maxRGB = $r Then
$h = 60 * Mod((($g - $b) / $deltaRGB), 6)
ElseIf $maxRGB = $g Then
$h = 60 * ((($b - $r) / $deltaRGB) + 2)
Else
$h = 60 * ((($r - $g) / $deltaRGB) + 4)
EndIf
If $maxRGB = 0 Then
$s = 0
Else
$s = $deltaRGB / $maxRGB
EndIf
$v = $maxRGB
Local $aHSV[3] = [$H, $S, $V]
Return $aHSV
EndFunc
Func Min($a, $b)
Return ($a < $b) ? $a : $b
EndFunc
Func Max($a, $b)
Return ($a > $b) ? $a : $b
EndFunc
Func Min3($a, $b, $c)
Return Min(Min($a, $b), $C)
EndFunc
Func Max3($a, $b, $c)
Return Max(Max($a, $b), $C)
EndFunc
Alles anzeigen
Die Ergebnisse sehen ganz passable aus, aber noch nicht gut genug, da man immer noch Farbfragmente innerhalb der Farbbereiche sieht.
Habt ihr noch Ideen?