;Coded by UEZ build 2023-03-16
#include <Array.au3>
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
_GDIPlus_Startup()
Global $hGUI = GUICreate("GDI+ Color Sorting / Grouping Test", 800, 120); 520)
GUISetState()
Global $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)
Global $hPen = _GDIPlus_PenCreate(0)
_GDIPlus_GraphicsClear($hGraphic)
SRandom(80)
Global $aColortable[511], $i, $y = 0
For $i = 0 To UBound($aColortable) - 1
$aColortable[$i] = Int(Random() * 0x1000000)
Next
; For $i = 0 To UBound($aColortable) - 1
; Do
; $iColor = Int(Random() * 0xFFFFFF)
; $a = RGB2HSV($iColor)
; Until $a[2] > 0.98 And $a[1] > 0.98
; $aColortable[$i] = $iColor
; Next
DrawColors($y, "Random")
; _ArraySort($aColortable)
; $y += 40
; DrawColors($y, "Default Array Sort")
; SortByCMYK($aColortable)
; $y += 40
; DrawColors($y, "CMYK")
; SortByLum($aColortable)
; $y += 40
; DrawColors($y, "Luminosity")
; SortByDistance($aColortable)
; $y += 40
; DrawColors($y, "Distance")
; SortByHSL($aColortable)
; $y += 40
; DrawColors($y, "HSL by L")
; SortByHSV($aColortable)
; $y += 40
; DrawColors($y, "HSV by V")
; SortByHSL($aColortable, 1)
; $y += 40
; DrawColors($y, "HSL / HSV by H")
; SortByHSL2($aColortable)
; $y += 40
; DrawColors($y, "HSV 2")
; SortByGroupingHSL($aColortable)
; $y += 40
; DrawColors($y, "Grouping HSL by dist.")
; SortByGroupingHSV($aColortable)
; $y += 40
; DrawColors($y, "Grouping HSV by LAB")
; SortByLAB($aColortable)
; $y += 40
; DrawColors($y, "LAB")
SortByBrightColor($aColortable)
$y += 40
DrawColors($y, "Brightness Colorness")
SortByLAB_Brightness($aColortable)
$y += 40
DrawColors($y, "LAB Brightness")
While GUIGetMsg() <> $GUI_EVENT_CLOSE
Sleep(10)
WEnd
_GDIPlus_PenDispose($hPen)
_GDIPlus_GraphicsDispose($hGraphic)
_GDIPlus_Shutdown()
GUIDelete()
Exit
Func DrawColors($y, $txt = 0, $array = $aColortable)
If UBound($array, 2) Then
For $i = 0 To UBound($array) - 1
_GDIPlus_PenSetColor($hPen, BitOR(0xFF000000, $array[$i][0]))
_GDIPlus_GraphicsDrawLine($hGraphic, $i, $y, $i, $y + 32, $hPen)
Next
Else
For $i = 0 To UBound($array) - 1
_GDIPlus_PenSetColor($hPen, BitOR(0xFF000000, $array[$i]))
_GDIPlus_GraphicsDrawLine($hGraphic, $i, $y, $i, $y + 32, $hPen)
Next
EndIf
If $txt Then _GDIPlus_GraphicsDrawString($hGraphic, $txt, $i + 8, $y + 4, "Arial", 16, Default, 0xFFFFFFFF)
EndFunc
Func SortByCMYK(ByRef $aColortable) ;http://www.easyrgb.com/en/math.php
Local $aColortable2[UBound($aColortable)][6]
Local $a, $i
For $i = 0 To UBound($aColortable) - 1
$a = RGA2CMYK($aColortable[$i])
$aColortable2[$i][0] = $aColortable[$i]
$aColortable2[$i][1] = $a[0] ;C
$aColortable2[$i][2] = $a[1] ;M
$aColortable2[$i][3] = $a[2] ;Y
$aColortable2[$i][4] = $a[3] ;K
$aColortable2[$i][5] = Sqrt($a[0] ^ 2 + $a[1] ^ 2 + $a[2] ^ 2 + $a[3] ^ 2)
Next
Local $aSort[] = [5, 3]
_ArraySort_MultiColumn($aColortable2, $aSort, 1, 0)
For $i = 0 To UBound($aColortable2) - 1
$aColortable[$i] = $aColortable2[$i][0]
Next
Dim $aColortable2[0]
EndFunc
Func SortByLum(ByRef $aColortable)
Local $aColortable2[UBound($aColortable)][4], $a, $i, $r, $g, $b, $lum, $h2, $lum2, $v2, $repetitions = 1
For $i = 0 To UBound($aColortable) - 1
$r = BitShift(BitAND($aColortable[$i], 0xFF0000), 16)
$g = BitShift(BitAND($aColortable[$i], 0xFF00), 8)
$b = BitAND($aColortable[$i], 0xFF)
$lum = Sqrt(0.241 * $r + 0.691 * $g + 0.068 * $b)
$a = RGB2HSV($aColortable[$i])
$h2 = Int($a[0] * $repetitions)
$lum2 = Int($lum * $repetitions)
$v2 = Int($a[2] * $repetitions)
;~ If Mod($h2, 2) = 1 Then
;~ $v2 = $repetitions - $v2
;~ $lum2 = $repetitions - $lum
;~ EndIf
$aColortable2[$i][0] = $aColortable[$i]
$aColortable2[$i][1] = $h2 ;H
$aColortable2[$i][2] = $lum2 ;S
$aColortable2[$i][3] = $v2 ;V
Next
;~ Local $aSort[] = [2, 3]
;~ _ArraySort_MultiColumn($aColortable2, $aSort, 0, 0)
;~ DrawColors(96, "Test", $aColortable2)
Local $aSort2[][] = [[2, 0], [3, 0]]
_ArrayMultiColSort($aColortable2, $aSort2)
For $i = 0 To UBound($aColortable2) - 1
$aColortable[$i] = $aColortable2[$i][0]
Next
Dim $aColortable2[0]
EndFunc
Func SortByLAB_Brightness(ByRef $aColortable)
Local $iDim = UBound($aColortable)
Local $aLAB[$iDim][4], $aTmp
For $i = 0 To $iDim - 1
$aTmp = _RGB2LAB($aColortable[$i])
$aLAB[$i][0] = $aTmp[0]
$aLAB[$i][1] = $aTmp[1]
$aLAB[$i][2] = $aTmp[2]
$aLAB[$i][3] = $i
Next
_ArraySort($aLAB, 0, 0, 0, 0)
$aTmp = $aColortable
For $i = 0 To $iDim - 1
$aColortable[$i] = $aTmp[$aLAB[$i][3]]
Next
EndFunc
Func SortByLAB(ByRef $aColortable, $iStartRGB = 0) ;by eukalyptus
Local $iDim = UBound($aColortable), $iDim2 = UBound($aColortable, 2)
Local $aLAB[$iDim][2], $i
If $iDim2 Then
For $i = 0 To $iDim - 1
$aLAB[$i][0] = _RGB2LAB($aColortable[$i][0])
Next
Else
For $i = 0 To $iDim - 1
$aLAB[$i][0] = _RGB2LAB($aColortable[$i])
Next
EndIf
Local $aLastLAB = _RGB2LAB($iStartRGB)
Local $aSort[$iDim], $fD, $fMin, $iIdx
For $i = 0 To $iDim - 1
$fMin = 2 ^ 32
$iIdx = -1
For $j = 0 To $iDim - 1
If $aLAB[$j][1] Then ContinueLoop
$fD = Sqrt((($aLAB[$j][0])[0] - $aLastLAB[0]) ^ 2 + (($aLAB[$j][0])[1] - $aLastLAB[1]) ^ 2 + (($aLAB[$j][0])[2] - $aLastLAB[2]) ^ 2)
If $fD < $fMin Then
$fMin = $fD
$iIdx = $j
EndIf
Next
$aSort[$i] = $iIdx
$aLastLAB = $aLAB[$iIdx][0]
$aLAB[$iIdx][1] = True
Next
$aTmp = $aColortable
For $i = 0 To $iDim - 1
If $iDim2 Then
$aColortable[$i][0] = $aTmp[$aSort[$i]][0]
Else
$aColortable[$i] = $aTmp[$aSort[$i]]
EndIf
Next
EndFunc
Func _RGB2LAB($iRGB) ;by eukalyptus
Local $aRGB[3], $i
$aRGB[0] = BitAND(BitShift($iRGB, 16), 0xFF) / 255
$aRGB[1] = BitAND(BitShift($iRGB, 8), 0xFF) / 255
$aRGB[2] = BitAND($iRGB, 0xFF) / 255
For $i = 0 To 2
If $aRGB[$i] > 0.04045 Then
$aRGB[$i] = (($aRGB[$i] + 0.055) / 1.055) ^ 2.4
Else
$aRGB[$i] = $aRGB[$i] / 12.92
EndIf
$aRGB[$i] *= 100
Next
Local $aXYZ[3]
$aXYZ[0] = ($aRGB[0] * 0.4124 + $aRGB[1] * 0.3576 + $aRGB[2] * 0.1805) / 95.047
$aXYZ[1] = ($aRGB[0] * 0.2126 + $aRGB[1] * 0.7152 + $aRGB[2] * 0.0722) / 100.0
$aXYZ[2] = ($aRGB[0] * 0.0193 + $aRGB[1] * 0.1192 + $aRGB[2] * 0.9505) / 108.883
For $i = 0 To 2
If $aXYZ[$i] > 0.008856 Then
$aXYZ[$i] = $aXYZ[$i] ^ 0.3333333333333333
Else
$aXYZ[$i] = (7.787 * $aXYZ[$i]) + (16 / 116)
EndIf
Next
Local $aLAB[3]
$aLAB[0] = (116 * $aXYZ[1]) - 16
$aLAB[1] = 500 * ($aXYZ[0] - $aXYZ[1])
$aLAB[2] = 200 * ($aXYZ[1] - $aXYZ[2])
Return $aLAB
EndFunc
Func SortByDistance(ByRef $aColortable, $iDir = 0)
Local $i, $aTmp[2], $swapped
If $iDir = 0 Then ;sort ascending
If UBound($aColortable, 2) Then
Do ;bubblesort -> slow!
$swapped = 0
For $i = 0 To UBound($aColortable) - 2
Distance($aColortable[$i][0], $aColortable[$i + 1][0])
If @extended Then
$aTmp[0] = $aColortable[$i][0]
$aColortable[$i][0] = $aColortable[$i + 1][0]
$aColortable[$i + 1][0] = $aTmp[0]
$swapped = 1
EndIf
Next
Until $swapped = 0
Else
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
EndIf
Else ;sort descending
If UBound($aColortable, 2) Then
Do ;bubblesort -> slow!
$swapped = 0
For $i = UBound($aColortable) - 1 To 1 Step -1
Distance($aColortable[$i][0], $aColortable[$i - 1][0])
If @extended Then
$aTmp[0] = $aColortable[$i][0]
$aColortable[$i][0] = $aColortable[$i - 1][0]
$aColortable[$i - 1][0] = $aTmp[0]
$swapped = 1
EndIf
Next
Until $swapped = 0
Else
Do ;bubblesort -> slow!
$swapped = 0
For $i = UBound($aColortable) - 1 To 1 Step -1
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
EndIf
EndIf
EndFunc
Func SortByHSL(ByRef $aColortable, $sc = 3)
Local $aColortable2[UBound($aColortable)][5]
Local $a, $i
For $i = 0 To UBound($aColortable) - 1
$a = RGB2HSL($aColortable[$i])
$aColortable2[$i][0] = $aColortable[$i]
$aColortable2[$i][1] = $a[0] ;H
$aColortable2[$i][2] = $a[1] ;S
$aColortable2[$i][3] = $a[2] ;L
$aColortable2[$i][4] = Sqrt($a[0] ^ 2 + $a[1] ^ 4 + $a[2] ^ 8) ;Sqrt(($a[0] / 360) ^ 2 + $a[1] ^ 2 + $a[2] ^ 2)
Next
$sc = Max(Min($sc, 4), 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 = 3)
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, $sortmode = 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
$sortmode = Max(Min($sortmode, 2), 1)
Switch $sortmode
Case 1
_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)
Case 2
SortByDistance($red, 1)
SortByDistance($orange)
SortByDistance($yellow, 1)
SortByDistance($lime)
SortByDistance($green, 1)
SortByDistance($turqoise)
SortByDistance($cyan, 1)
SortByDistance($cobalt)
SortByDistance($blue, 1)
SortByDistance($violet)
SortByDistance($magenta, 1)
SortByDistance($crimson)
SortByDistance($grey, 1)
EndSwitch
$i = 0
For $j = 0 To UBound($crimson) - 1
$aColortable[$i] = $crimson[$j][0]
$i += 1
Next
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($grey) - 1
$aColortable[$i] = $grey[$j][0]
$i += 1
Next
EndFunc
Func SortByGroupingHSV(ByRef $aColortable, $sc = 2, $sortmode = 3)
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
$sortmode = Max(Min($sortmode, 3), 1)
Switch $sortmode
Case 1
_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)
Case 2
SortByDistance($red, 1)
SortByDistance($orange)
SortByDistance($yellow, 1)
SortByDistance($lime)
SortByDistance($green, 1)
SortByDistance($turqoise)
SortByDistance($cyan, 1)
SortByDistance($cobalt)
SortByDistance($blue, 1)
SortByDistance($violet)
SortByDistance($magenta, 1)
SortByDistance($crimson)
SortByDistance($grey, 1)
Case 3
SortByLAB($red)
SortByLAB($orange)
SortByLAB($yellow)
SortByLAB($lime)
SortByLAB($green)
SortByLAB($turqoise)
SortByLAB($cyan)
SortByLAB($cobalt)
SortByLAB($blue)
SortByLAB($violet)
SortByLAB($magenta)
SortByLAB($crimson)
SortByLAB($grey)
EndSwitch
$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 SortByHSL2(ByRef $aColortable) ;by Mars
Local $aColortable2[UBound($aColortable)][9]
Local $a, $i, $hsl_
For $i = 0 To UBound($aColortable) - 1
$a = _RGB2LAB($aColortable[$i])
$hsl_ = RGB2HSL($aColortable[$i])
$aColortable2[$i][0] = $aColortable[$i]
$aColortable2[$i][1] = $a[0] ; LAB -> L
$aColortable2[$i][2] = Sqrt($a[1]^2 + $a[2]^2) ; chroma
$aColortable2[$i][3] = Abs($a[0] - 50) ; L umformen um "hell und dunkel" rauszufiltern
$aColortable2[$i][4] = $hsl_[0] ; HSL -> H (könnte man via Farbwinkel aus LAB auch machen, hab ich ausprobiert, sah nicht so schön aus)
Next
Local $10 = Int(UBound($aColortable)/10)
_ArraySort($aColortable2, 0, 0, 0, 2) ; chroma -> ziemlich "unbunte" farben herausfiltern (10%)
_ArraySort($aColortable2, 1, 1 * $10 + 1, 0 * $10, 3) ; abs(L-50) -> sehr helle und sehr dunkle Farben herausfiltern
_ArraySort($aColortable2, 0, 1 * $10 + 1, 5 * $10, 2) ; chroma -> von den hellen und dunklen Farben die unbuntesten raussuchen (nochmal 10%)
_ArraySort($aColortable2, 0, 0 * $10 + 0, 2 * $10, 1) ; Die packt man links an das erste 5tel als eine Art "Pseudograustufenliste" (darin sind 20% aller Farben)
_ArraySort($aColortable2, 0, 2 * $10 + 1, 0 * $10, 1) ; L -> sortiere nach Helligkeit
_ArraySort($aColortable2, 0, 2 * $10 + 1, 6 * $10, 4) ; H -> Sortiere nach Hue (1x für niedrige Helligkeit)
_ArraySort($aColortable2, 1, 6 * $10 + 1, 0 * $10, 4) ; H -> Sortiere nach Hue (1x für hohe Helligkeit)
For $i = 0 To UBound($aColortable2) - 1
$aColortable[$i] = $aColortable2[$i][0]
Next
Dim $aColortable2[0]
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 Round($H, 0)
Case 0 To 14, 345 To 359
Return "red"
Case 15 To 44
Return "orange"
Case 45 To 74
Return "yellow"
Case 75 To 104
Return "lime"
Case 105 To 134
Return "green"
Case 135 To 164
Return "turqoise"
Case 165 To 194
Return "cyan"
Case 195 To 224
Return "cobalt"
Case 225 To 254
Return "blue"
Case 255 To 284
Return "violet"
Case 285 To 314
Return "magenta"
Case 315 To 344
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) ;http://www.easyrgb.com/en/math.php
Local $var_r = BitAND(BitShift($iColor, 16), 255) / 255, $var_g = BitAND(BitShift($iColor, 8), 255) / 255, $var_b = BitAND($iColor, 255) / 255
Local $H, $S, $L, $var_Min, $var_Max, $del_Max, $del_Max2, $del_R, $del_G, $del_B
$var_Min = Min3($var_r, $var_g, $var_b)
$var_Max = Max3($var_r, $var_g, $var_b)
$del_Max = $var_Max - $var_Min
$L = ($var_Max + $var_Min) / 2
If $del_Max = 0 Then
$H = 0
$S = 0
Else
$S = $L < 0.5 ? $del_Max / ($var_Max + $var_Min) : $del_Max / (2 - $var_Max - $var_Min)
$del_Max2 = $del_Max / 2
$del_R = ((($var_Max - $var_R) / 6) + $del_Max2) / $del_Max
$del_G = ((($var_Max - $var_G) / 6) + $del_Max2) / $del_Max
$del_B = ((($var_Max - $var_B) / 6) + $del_Max2) / $del_Max
If ($var_R = $var_Max) Then
$H = $del_B - $del_G
Elseif $var_G = $var_Max Then
$H = 0.333333333333333 + $del_R - $del_B
Elseif $var_B = $var_Max Then
$H = 0.666666666666667 + $del_G - $del_R
EndIf
If $H < 0 Then $H += 1
If $H > 1 Then $H -= 1
EndIf
Local $aHSL[3] = [$H * 360, $S, $L]
Return $aHSL
EndFunc
Func RGB2HSV($iColor) ;http://www.easyrgb.com/en/math.php
Local $var_r = BitAND(BitShift($iColor, 16), 255) / 255, $var_g = BitAND(BitShift($iColor, 8), 255) / 255, $var_b = BitAND($iColor, 255) / 255
Local $H, $S, $V, $var_Min, $var_Max, $del_Max, $del_Max2, $del_R, $del_G, $del_B
$var_Min = Min3($var_r, $var_g, $var_b)
$var_Max = Max3($var_r, $var_g, $var_b)
$del_Max = $var_Max - $var_Min
$V = $var_Max
If $del_Max = 0 Then
$H = 0
$S = 0
Else
$S = $del_Max / $var_Max
$del_Max2 = $del_Max / 2
$del_R = ((($var_Max - $var_R) / 6) + $del_Max2) / $del_Max
$del_G = ((($var_Max - $var_G) / 6) + $del_Max2) / $del_Max
$del_B = ((($var_Max - $var_B) / 6) + $del_Max2) / $del_Max
If $var_R = $var_Max Then
$H = $del_B - $del_G
ElseIf $var_G = $var_Max Then
$H = 0.333333333333333 + $del_R - $del_B
ElseIf $var_B = $var_Max Then
$H = 0.666666666666667 + $del_G - $del_R
EndIf
If $H < 0 Then $H += 1
If $H > 1 Then $H -= 1
EndIf
Local $aHSV[3] = [$H * 360, $S, $V]
Return $aHSV
EndFunc
Func RGA2CMYK($iColor)
Local $r = BitAND(BitShift($iColor, 16), 255), $g = BitAND(BitShift($iColor, 8), 255), $b = BitAND($iColor, 255)
Local $C = 1 - ($r / 255), $M = 1 - ($G / 255), $Y = 1 - ($B / 255), $K = 1
If ($C < $K) Then $K = $C
If ($M < $K) Then $K = $M
If ($Y < $K) Then $K = $Y
If ($K = 1) Then ;Black only
$C = 0
$M = 0
$Y = 0
Else
$C = ($C - $K) / (1 - $K)
$M = ($M - $K) / (1 - $K)
$Y = ($Y - $K) / (1 - $K)
EndIf
Local $aCMYK[] = [$C, $M, $Y, $K]
Return $aCMYK
EndFunc
Func SortByBrightColor(ByRef $List) ; by fee
Local Const _
$High = UBound($List)
Local $Sort[$High][$High]
For $a = 0 To $High - 1
$Redd = BitAnd(BitShift($List[$a], 16), 0xFF)
$Gren = BitAnd(BitShift($List[$a], 8), 0xFF)
$Blue = BitAnd( $List[$a], 0xFF)
$Mini = Min3($Redd, $Gren, $Blue)
$Maxi = Max3($Redd, $Gren, $Blue)
$Dist = $Maxi - $Mini
$Luma = Round(($Redd * 0.299) + ($Gren * 0.587) + ($Blue * 0.114))
$Sort[$Luma][$Dist] = $List[$a]
Next
$c = 0
For $a = 0 To $High - 1
For $b = 0 To $High - 1
If $Sort[$a][$b] = '' Then ContinueLoop
$List[$c] = $Sort[$a][$b]
$c += 1
Next
Next
EndFunc ;==>SortByBrightColor
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
; #FUNCTION# =============================================================================
; Name.............: _ArraySort_MultiColumn
; Description ...: sorts an array at given colums (multi colum sort)
; Syntax...........: _ArraySort_MultiColumn(ByRef $aSort, ByRef $aIndices)
; Parameters ...: $aSort - array to sort
; $aIndices - array with colum indices which should be sorted in specified order - zero based
; $oDir/$iDir - sort direction - if set to 1, sort descending else ascending. $oDir is for the 1st row,
; $iDir for the remaining rows
; $iStart - where to start to sort - 0 = 0 based array, 1 = 1 based array
; Author .........: UEZ
; Version ........: v0.80 build 2019-01-26 Beta
; =========================================================================================
Func _ArraySort_MultiColumn(ByRef $aSort, ByRef $aIndices, $oDir = 0, $iDir = 0, $iStart = 0)
If Not IsArray($aIndices) Or Not IsArray($aSort) Then Return SetError(1, 0, 0) ;checks if $aIndices is an array
If UBound($aSort, 2) = 0 Then Return SetError(4, 0, 0) ;array is 1D only
If UBound($aIndices) > UBound($aSort, 2) Then Return SetError(2, 0, 0) ;check if $aIndices array is greater the $aSort array
Local $1st, $2nd, $x, $j, $k, $l = 0
For $x = 0 To UBound($aIndices) - 1 ;check if array content makes sense
If Not IsInt($aIndices[$x]) Then Return SetError(3, 0, 0) ;array content is not numeric
Next
$iStart = Int($iStart) < 0 ? 0 : Int($iStart) > 1 ? 1 : Int($iStart)
If UBound($aIndices) = 1 Then Return _ArraySort($aSort, $oDir, $iStart, 0, $aIndices[0]) ;check if only one index is given
_ArraySort($aSort, $oDir, $iStart, 0, $aIndices[0])
Do
$1st = $aIndices[$l]
$2nd = $aIndices[$l + 1]
$j = 0
$k = 1
While $k < UBound($aSort)
If $aSort[$j][$1st] <> $aSort[$k][$1st] Then
If $k - $j > 1 Then
_ArraySort($aSort, $iDir, $j, $k - 1, $2nd)
$j = $k
Else
$j = $k
EndIf
EndIf
$k += 1
WEnd
If $k - $j > 1 Then _ArraySort($aSort, $iDir, $j, $k, $2nd)
$l += 1
Until $l = UBound($aIndices) - 1
Return 1
EndFunc ;==>_ArraySort_MultiColumn
; #FUNCTION# ====================================================================================================================
; Name...........: _ArrayMultiColSort
; Description ...: Sort 2D arrays on several columns
; Syntax.........: _ArrayMultiColSort(ByRef $aArray, $aSortData[, $iStart = 0[, $iEnd = 0]])
; Parameters ....: $aArray - The 2D array to be sorted
; $aSortData - 2D array holding details of the sort format
; Format: [Column to be sorted, Sort order]
; Sort order can be either numeric (0/1 = ascending/descending) or a ordered string of items
; Any elements not matched in string are left unsorted after all sorted elements
; $iStart - Element of array at which sort starts (default = 0)
; $iEnd - Element of array at which sort endd (default = 0 - converted to end of array)
; Requirement(s).: v3.3.8.1 or higher
; Return values .: Success: No error
; Failure: @error set as follows
; @error = 1 with @extended set as follows (all refer to $sIn_Date):
; 1 = Array to be sorted not 2D
; 2 = Sort data array not 2D
; 3 = More data rows in $aSortData than columns in $aArray
; 4 = Start beyond end of array
; 5 = Start beyond End
; @error = 2 with @extended set as follows:
; 1 = Invalid string parameter in $aSortData
; 2 = Invalid sort direction parameter in $aSortData
; 3 = Invalid column index in $aSortData
; Author ........: Melba23
; Remarks .......: Columns can be sorted in any order
; Example .......; Yes
; ===============================================================================================================================
Func _ArrayMultiColSort(ByRef $aArray, $aSortData, $iStart = 0, $iEnd = 0)
; Errorchecking
; 2D array to be sorted
If UBound($aArray, 2) = 0 Then
Return SetError(1, 1, "")
EndIf
; 2D sort data
If UBound($aSortData, 2) <> 2 Then
Return SetError(1, 2, "")
EndIf
If UBound($aSortData) > UBound($aArray) Then
Return SetError(1, 3)
EndIf
For $i = 0 To UBound($aSortData) - 1
If $aSortData[$i][0] < 0 Or $aSortData[$i][0] > UBound($aArray, 2) -1 Then
Return SetError(2, 3, "")
EndIf
Next
; Start element
If $iStart < 0 Then
$iStart = 0
EndIf
If $iStart >= UBound($aArray) - 1 Then
Return SetError(1, 4, "")
EndIf
; End element
If $iEnd <= 0 Or $iEnd >= UBound($aArray) - 1 Then
$iEnd = UBound($aArray) - 1
EndIf
; Sanity check
If $iEnd <= $iStart Then
Return SetError(1, 5, "")
EndIf
Local $iCurrCol, $iChunk_Start, $iMatchCol
; Sort first column
__AMCS_SortChunk($aArray, $aSortData, 0, $aSortData[0][0], $iStart, $iEnd)
If @error Then
Return SetError(2, @extended, "")
EndIf
; Now sort within other columns
For $iSortData_Row = 1 To UBound($aSortData) - 1
; Determine column to sort
$iCurrCol = $aSortData[$iSortData_Row][0]
; Create arrays to hold data from previous columns
Local $aBaseValue[$iSortData_Row]
; Set base values
For $i = 0 To $iSortData_Row - 1
$aBaseValue[$i] = $aArray[$iStart][$aSortData[$i][0]]
Next
; Set start of this chunk
$iChunk_Start = $iStart
; Now work down through array
For $iRow = $iStart + 1 To $iEnd
; Match each column
For $k = 0 To $iSortData_Row - 1
$iMatchCol = $aSortData[$k][0]
; See if value in each has changed
If $aArray[$iRow][$iMatchCol] <> $aBaseValue[$k] Then
; If so and row has advanced
If $iChunk_Start < $iRow - 1 Then
; Sort this chunk
__AMCS_SortChunk($aArray, $aSortData, $iSortData_Row, $iCurrCol, $iChunk_Start, $iRow - 1)
If @error Then
Return SetError(2, @extended, "")
EndIf
EndIf
; Set new base value
$aBaseValue[$k] = $aArray[$iRow][$iMatchCol]
; Set new chunk start
$iChunk_Start = $iRow
EndIf
Next
Next
; Sort final section
If $iChunk_Start < $iRow - 1 Then
__AMCS_SortChunk($aArray, $aSortData, $iSortData_Row, $iCurrCol, $iChunk_Start, $iRow - 1)
If @error Then
Return SetError(2, @extended, "")
EndIf
EndIf
Next
EndFunc ;==>_ArrayMultiColSort
; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........: __AMCS_SortChunk
; Description ...: Sorts array section
; Author ........: Melba23
; Remarks .......:
; ===============================================================================================================================
Func __AMCS_SortChunk(ByRef $aArray, $aSortData, $iRow, $iColumn, $iChunkStart, $iChunkEnd)
Local $aSortOrder
; Set default sort direction
Local $iSortDirn = 1
; Need to prefix elements?
If IsString($aSortData[$iRow][1]) Then
; Split elements
$aSortOrder = StringSplit($aSortData[$iRow][1], ",")
If @error Then
Return SetError(1, 1, "")
EndIf
; Add prefix to each element
For $i = $iChunkStart To $iChunkEnd
For $j = 1 To $aSortOrder[0]
If $aArray[$i][$iColumn] = $aSortOrder[$j] Then
$aArray[$i][$iColumn] = StringFormat("%02i-", $j) & $aArray[$i][$iColumn]
ExitLoop
EndIf
Next
; Deal with anything that does not match
If $j > $aSortOrder[0] Then
$aArray[$i][$iColumn] = StringFormat("%02i-", $j) & $aArray[$i][$iColumn]
EndIf
Next
Else
Switch $aSortData[$iRow][1]
Case 0, 1
; Set required sort direction if no list
If $aSortData[$iRow][1] Then
$iSortDirn = -1
Else
$iSortDirn = 1
EndIf
Case Else
Return SetError(1, 2, "")
EndSwitch
EndIf
; Sort the chunk
Local $iSubMax = UBound($aArray, 2) - 1
__ArrayQuickSort2D($aArray, $iSortDirn, $iChunkStart, $iChunkEnd, $iColumn, $iSubMax)
; Remove any prefixes
If IsString($aSortData[$iRow][1]) Then
For $i = $iChunkStart To $iChunkEnd
$aArray[$i][$iColumn] = StringTrimLeft($aArray[$i][$iColumn], 3)
Next
EndIf
EndFunc ;==>__AMCS_SortChunk
Alles anzeigen