1. Dashboard
  2. Mitglieder
    1. Letzte Aktivitäten
    2. Benutzer online
    3. Team
    4. Mitgliedersuche
  3. Forenregeln
  4. Forum
    1. Unerledigte Themen
  • Anmelden
  • Registrieren
  • Suche
Alles
  • Alles
  • Artikel
  • Seiten
  • Forum
  • Erweiterte Suche
  1. AutoIt.de - Das deutschsprachige Forum.
  2. Mitglieder
  3. UEZ

Beiträge von UEZ

  • Basic Image Editor als Erweiterung für ein Screenshot Tool

    • UEZ
    • 24. Mai 2023 um 11:03

    Wie gesagt, ist die Version nur ein "Proof-of-Concept" Version und ich würde dem Status höchstens ein "Alpha" geben, da vieles nicht richtig funktioniert bzw. nicht implementiert ist.

    Ich weiß nicht, wie aufwändig es ist, aus dem Windows Screenshooter den Image Editor zu extrahieren.

    Ich habe auch keine Ambitionen diesen Image Editor weiterzuentwickeln - sorry.

  • Basic Image Editor als Erweiterung für ein Screenshot Tool

    • UEZ
    • 24. Mai 2023 um 10:09
    Zitat von gmmg

    Außerdem wäre die Frage, wie ich es hinbekomme, dass er beim start keinen Screenshot macht, sondern ich eine BMP Datei übergeben kann.

    In Zeile 26 wird ein Bildschirm Foto erstellt und benutzt. Einfach den Bereich durch folgenden Code ersetzen:

    AutoIt
    Opt("MustDeclareVars", 1)
    
    Global $sFile = FileOpenDialog("Select an image", "", "Images (*.jpg;*.bmp;*.png;*.gif)")
    If @error Then Exit MsgBox(16, "Error", "No image has been selected")
    Global Const $dll = DllOpen("user32.dll")
    _GDIPlus_Startup()
    Global $ghGDIPDll = $__g_hGDIPDll
    Global $aDPI = _GDIPlus_GraphicsGetDPIRatio()
    ;~ Global $hBMP_Screen = _ScreenCapture_Capture("", 0, 0, 1920, 1080)
    ;~ Global $hBmp = _GDIPlus_BitmapCreateFromHBITMAP($hBMP_Screen)
    ;~ _WinAPI_DeleteObject($hBMP_Screen)
    Global $hBmp = _GDIPlus_ImageLoadFromFile($sFile)
    Global $bW = _GDIPlus_ImageGetWidth($hBmp)
    Global $bH = _GDIPlus_ImageGetHeight($hBmp)
    Alles anzeigen
    Zitat von gmmg

    AutoIt Windows Screenshooter v1.84 Build 2019-08-18\AutoIt Windows Screenshooter\_Source\Windows Screenshooter.au3"(122,107) : error: $GDIP_WrapModeTileFlipXY previously declared as a 'Const'.

    Global Enum $GDIP_WrapModeTile, $GDIP_WrapModeTileFlipX, $GDIP_WrapModeTileFlipY, $GDIP_WrapModeTileFlipXY,

    Einfach die Zeile auskommentieren, da die Variablen bereits deklariert sind. Zu der damaligen Zeit war dies nicht der Fall.

    Die Funktion

    AutoIt
    Func Save_Bitmap()
        Return 1
    EndFunc

    kannst du versuchen mit "Leben" zu füllen, um das Resultat in eine Bilddatei zu speichern.

  • Basic Image Editor als Erweiterung für ein Screenshot Tool

    • UEZ
    • 23. Mai 2023 um 15:54

    Der Editor war nie als eigenständiges Tool gedacht, sondern nur als "Proof-of-Concept" Version. Die stabilere Version ist im Windows Screenshooter Tool integriert.

    Diese ältere Version scheint einigermaßen zu funktionieren: Basic Image Editor.au3

  • MsgBox hooken und Countdown hinzufügen

    • UEZ
    • 28. April 2023 um 13:10

    funkey : Prima, werde es testen und mich melden, falls ich was finde...

  • MsgBox hooken und Countdown hinzufügen

    • UEZ
    • 27. April 2023 um 17:08
    Zitat von funkey

    Hallo,

    hab das mal in meine HookDlgBox-UDF eingebaut.

    HookDlgBox.au3
    AutoIt
    #include-once
    #include <WinAPI.au3>
    #include <Timers.au3>
    
    Global Const $tagCBT_CREATEWND = "ptr lpcs;HWND tagCBT_CREATEWND"
    Global Const $tagCREATESTRUCT = "ptr lpCreateParams;handle hInstance;HWND hMenu;HWND hwndParent;int cy;int cx;int y;int x;LONG style;ptr lpszName;ptr lpszClass;DWORD dwExStyle"
    
    Global $g__hProcDlgBox = DllCallbackRegister("__DlgBox_CbtHookProc", "LRESULT", "int;WPARAM;LPARAM")
    Global $g__TIdDlgBox = _WinAPI_GetCurrentThreadId()
    Global $g__hHookDlgBox = _WinAPI_SetWindowsHookEx($WH_CBT, DllCallbackGetPtr($g__hProcDlgBox), 0, $g__TIdDlgBox)
    
    Global Const $g__MaxDlgBtns = 5 ; maximum of 5 buttons to rename text
    Global Const $g__MaxDlgItemId = 11 ; maximun ID of buttons to search is 11 as this is the maximun used in Messagebox
    
    Global $g__DlgBoxPosX, $g__DlgBoxPosY, $g__DlgBoxWidth, $g__DlgBoxHeight
    Global $g__aDlgBoxBtnText[$g__MaxDlgBtns]
    
    Global $g__DlgBtnCount = 0
    Global $g_DlgBoxTimeout = 0
    Global $g_DlgBoxTimeCtrlNum, $g_DlgBoxTimeCtrlId
    Global $g_DlgBoxTimerId
    
    _DlgBox_SetDefaults()
    
    OnAutoItExitRegister("__DlgBox_UnregisterHook")
    
    
    Func _DlgBox_SetButtonNames($TxtBtn1 = Default, $TxtBtn2 = Default, $TxtBtn3 = Default, $TxtBtn4 = Default, $TxtBtn5 = Default)
        $g__aDlgBoxBtnText[0] = $TxtBtn1
        $g__aDlgBoxBtnText[1] = $TxtBtn2
        $g__aDlgBoxBtnText[2] = $TxtBtn3
        $g__aDlgBoxBtnText[3] = $TxtBtn4
        $g__aDlgBoxBtnText[4] = $TxtBtn5
    
        $g__DlgBtnCount = @NumParams
    EndFunc   ;==>_DlgBox_SetButtonNames
    
    Func _DlgBox_SetPosition($x = Default, $y = Default) ;only for MsgBox, not working and not needed for InputBox
        $g__DlgBoxPosX = $x
        $g__DlgBoxPosY = $y
    EndFunc   ;==>_DlgBox_SetPosition
    
    Func _DlgBox_SetSize($w = Default, $h = Default)
        $g__DlgBoxWidth = $w
        $g__DlgBoxHeight = $h
    EndFunc   ;==>_DlgBox_SetSize
    
    Func _DlgBox_SetDefaults()
        $g__DlgBoxPosX = Default
        $g__DlgBoxPosY = Default
        $g__DlgBoxWidth = Default
        $g__DlgBoxHeight = Default
        For $i = 0 To UBound($g__aDlgBoxBtnText) - 1
            $g__aDlgBoxBtnText[$i] = Default
        Next
        $g_DlgBoxTimeout = 0
    EndFunc   ;==>_DlgBox_SetDefaults
    
    Func _DlgBox_SetTimeOut($iTimeout = 0, $CtrlId = 1)
        $g_DlgBoxTimeout = $iTimeout
        $g_DlgBoxTimeCtrlNum = $CtrlId
    EndFunc
    
    Func __DlgBox_CbtHookProc($nCode, $wParam, $lParam)
        Local $tcw, $tcs
        Local $iSearch = 0
        Local $ahBtn[$g__DlgBtnCount]
        If $nCode < 0 Then
            Return _WinAPI_CallNextHookEx($g__hHookDlgBox, $nCode, $wParam, $lParam)
        EndIf
    
        Switch $nCode
            Case 3 ;5=HCBT_CREATEWND
                If _WinAPI_GetClassName(HWnd($wParam)) = "#32770" Then ;Dialog window class
                    $tcw = DllStructCreate($tagCBT_CREATEWND, $lParam)
                    $tcs = DllStructCreate($tagCREATESTRUCT, DllStructGetData($tcw, "lpcs"))
    
                    If $g__DlgBoxPosX <> Default Then DllStructSetData($tcs, "x", $g__DlgBoxPosX)
                    If $g__DlgBoxPosY <> Default Then DllStructSetData($tcs, "y", $g__DlgBoxPosY)
                    If $g__DlgBoxWidth <> Default Then DllStructSetData($tcs, "cx", $g__DlgBoxWidth)
                    If $g__DlgBoxHeight <> Default Then DllStructSetData($tcs, "cy", $g__DlgBoxHeight)
    
                    If $g_DlgBoxTimeout <> 0 Then
                        $g_DlgBoxTimerId = _Timer_SetTimer(HWnd($wParam), 1000, "_UpdateTime")
                    EndIf
                EndIf
            Case 5 ;5=HCBT_ACTIVATE
                If _WinAPI_GetClassName(HWnd($wParam)) = "#32770" Then ;Dialog window class
                    For $i = 1 To $g__MaxDlgItemId
                        If IsHWnd(_WinAPI_GetDlgItem($wParam, $i)) Then
                            If $g_DlgBoxTimeout > 0 Then
                                If $iSearch == $g_DlgBoxTimeCtrlNum - 1 Then
                                    $g_DlgBoxTimeCtrlId = $i
                                    If $g__aDlgBoxBtnText[$iSearch] <> Default Then _WinAPI_SetDlgItemText($wParam, $i, $g__aDlgBoxBtnText[$iSearch] & " [" & $g_DlgBoxTimeout & "]")
                                Else
                                    If $g__aDlgBoxBtnText[$iSearch] <> Default Then _WinAPI_SetDlgItemText($wParam, $i, $g__aDlgBoxBtnText[$iSearch])
                                EndIf
                            Else
                                If $g__aDlgBoxBtnText[$iSearch] <> Default Then _WinAPI_SetDlgItemText($wParam, $i, $g__aDlgBoxBtnText[$iSearch])
                            EndIf
    
                            $iSearch += 1
                            If $iSearch >= UBound($ahBtn) Then ExitLoop
                        EndIf
                    Next
                EndIf
            Case 4 ;4=HCBT_DESTROYWND
                If _WinAPI_GetClassName(HWnd($wParam)) = "#32770" Then ;Dialog window class
                    _Timer_KillTimer(HWnd($wParam), $g_DlgBoxTimerId)
                    $g_DlgBoxTimeout = 0
                EndIf
        EndSwitch
        Return _WinAPI_CallNextHookEx($g__hHookDlgBox, $nCode, $wParam, $lParam)
    EndFunc   ;==>__DlgBox_CbtHookProc
    
    Func _UpdateTime($hWnd, $iMsg, $iIDTimer, $iTime)
        #forceref $hWnd, $iMsg, $iIDTimer, $iTime
    ;~     ConsoleWrite($hWnd&" - "&$iMsg&" - "&$iIDTimer&" - "&$iTime & @CRLF)
    
        $g_DlgBoxTimeout -= 1
        _WinAPI_SetDlgItemText($hWnd, $g_DlgBoxTimeCtrlId, $g__aDlgBoxBtnText[$g_DlgBoxTimeCtrlNum - 1] & " [" & $g_DlgBoxTimeout & "]")
        If $g_DlgBoxTimeout <= 0 Then
            WinClose($hWnd)
        EndIf
    EndFunc   ;==>_UpdateTime
    
    
    Func __DlgBox_UnregisterHook()
        _WinAPI_UnhookWindowsHookEx($g__hHookDlgBox)
        DllCallbackFree($g__hProcDlgBox)
    EndFunc   ;==>__DlgBox_UnregisterHook
    
    Func _WinAPI_SetDlgItemText($hDlg, $nIDDlgItem, $lpString)
        Local $aRet = DllCall('user32.dll', "int", "SetDlgItemText", _
                "hwnd", $hDlg, _
                "int", $nIDDlgItem, _
                "str", $lpString)
        Return $aRet[0]
    EndFunc   ;==>_WinAPI_SetDlgItemText
    Alles anzeigen
    HookDlgBox Timeout Beispiel
    AutoIt
    #include "HookDlgBox.au3"
    
    Global $Timeout = 5
    
    _DlgBox_SetTimeOut($Timeout, 1)
    _DlgBox_SetButtonNames("one", "two", "three")
    
    Global $iRet1 = MsgBox(3, "Test 1", "Custom button texts", $Timeout)
    ConsoleWrite($iRet1 & @CRLF)
    
    
    Global $iRet2 = MsgBox(3, "Test 2", "Custom button texts", $Timeout)
    ConsoleWrite($iRet2 & @CRLF)
    
    _DlgBox_SetTimeOut($Timeout, 2)
    
    Global $iRet3 = MsgBox(3, "Test 3", "Custom button texts")
    ConsoleWrite($iRet3 & @CRLF)
    
    _DlgBox_SetTimeOut($Timeout, 3)
    
    Global $iRet4 = MsgBox(3, "Test 4", "Custom button texts")
    ConsoleWrite($iRet4 & @CRLF)
    Alles anzeigen

    Dieses Beispiel funktioniert nicht:

    AutoIt
    #include <MsgBoxConstants.au3>
    #include "HookDlgBox.au3"
    
    Global $Timeout = 5
    
    _DlgBox_SetTimeOut($Timeout, 1)
    _DlgBox_SetButtonNames("Exit")
    MsgBox(BitOR($MB_TOPMOST, $MB_ICONINFORMATION), "Information", "View has been refreshed!", $Timeout)

    Anscheinend geht es nur mit $MB_YESNOCANCEL.

  • MsgBox hooken und Countdown hinzufügen

    • UEZ
    • 27. April 2023 um 14:34

    Velted : stimmt, danke für den Hinweis.

  • MsgBox hooken und Countdown hinzufügen

    • UEZ
    • 27. April 2023 um 14:04

    funkey :thumbup:

  • MsgBox hooken und Countdown hinzufügen

    • UEZ
    • 27. April 2023 um 11:17

    Oscar danke für deine Alternative!

    Das hier funktioniert jetzt:

    AutoIt
    ;Coded by UEZ build 2023-04-27 beta
    
    #include <Timers.au3>
    #include <WinAPIConstants.au3>
    #include <WinAPIGdi.au3>
    #include <WinAPIProc.au3>
    #include <WinAPISys.au3>
    #include <WindowsConstants.au3>
    
    Global $HCBT_ACTIVATE = 5, $g_hMsgBoxHook, $g_hMod, $g_hThreadID, $g_hSubMsgBox, $g_SubMsgBox, $g_lPrevWnd, $g_HWND, $g_idTImer, $g_
    Global $g_Time = 5
    
    Func _WinAPI_SetDlgItemText($hDlg, $nIDDlgItem, $lpString) ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setdlgitemtextw
        Local $aRet = DllCall("user32.dll", "int", "SetDlgItemText", "hwnd", $hDlg, "int", $nIDDlgItem, "str", $lpString)
        If @error Then Return SetError(@error, @extended, 0)
        Return $aRet[0]
    EndFunc   ;==>_WinAPI_SetDlgItemText
    
    Func _SubMsgBoxProc($hwnd, $iMsg, $wParam, $lParam)
        Switch $iMsg
            Case $WM_SHOWWINDOW
            Case $WM_CTLCOLORDLG, $WM_CTLCOLORSTATIC
    ;~             Local $tLOGBRUSH = DllStructCreate("uint lbStyle;long lbColor;ulong_ptr lbHatch")
    ;~             _WinAPI_SetBkColor($wParam, 0xFEDCBA)
    ;~             $tLOGBRUSH.lbColor = 0xFEDCBA
    ;~             DllCall("gdi32.dll", "handle", "CreateBrushIndirect", "struct*", $tLOGBRUSH)
    ;~             Return 0
            Case $WM_TIMER
                Local $sText = "Exit [" & $g_Time & "]"
                $g_Time -= 1
    ;~             ControlSetText($g_HWND, "", "[CLASS:Button; INSTANCE:1]", $sText)
                _WinAPI_SetDlgItemText($hWnd, $IDOK + 1, $sText)
                ConsoleWrite($g_Time & @CRLF)
    
                If $g_Time < 0 Then
                    _Timer_KillTimer($g_HWND, $g_idTImer)
                    _WinAPI_SetWindowLong($hwnd, $GWL_WNDPROC, $g_lPrevWnd)
                    GUIDelete($hwnd)
                EndIf
                Return 0
            Case $WM_DESTROY
                _Timer_KillTimer($g_HWND, $g_idTImer)
                _WinAPI_SetWindowLong($hwnd, $GWL_WNDPROC, $g_lPrevWnd)
        EndSwitch
        Return _WinAPI_CallWindowProc($g_lPrevWnd, $hWnd, $iMsg, $wParam, $lParam)
    EndFunc   ;==>_SubMsgBoxProc
    
    Func _CBTHookProc($nCode, $wParam, $lParam)
        If $nCode < 0 Then Return _WinAPI_CallNextHookEx($g_hMsgBoxHook, $nCode, $wParam, $lParam)
        Switch $nCode
            Case $HCBT_ACTIVATE
                $g_HWND = HWnd($wParam)
                If _WinAPI_GetClassName($g_HWND) = "#32770" Then
                    $g_idTImer = _Timer_SetTimer($g_HWND, 1000)
                    _WinAPI_SetDlgItemText($wParam, $IDOK, "Exit [" & $g_Time & "]")
                    $g_lPrevWnd = _WinAPI_SetWindowLong($g_HWND, $GWL_WNDPROC, DllCallbackGetPtr($g_SubMsgBox))
                EndIf
        EndSwitch
        Return _WinAPI_CallNextHookEx($g_hMsgBoxHook, $nCode, $wParam, $lParam)
    EndFunc   ;==>_CBTHookProc
    
    
    $g_SubMsgBox = DllCallbackRegister("_SubMsgBoxProc", "long", "hwnd;uint;wparam;lparam")
    $g_MsgProc = DllCallbackRegister("_CBTHookProc", "int", "uint;wparam;lparam")
    $g_hMod = _WinAPI_GetModuleHandle(0)
    $g_hThreadID = _WinAPI_GetCurrentThreadId()
    $g_hMsgBoxHook = _WinAPI_SetWindowsHookEx($WH_CBT, DllCallbackGetPtr($g_MsgProc), Null, $g_hThreadID)
    MsgBox(0, "Test", "This is a test message box with a counter!", $g_Time + 2)
    _WinAPI_UnhookWindowsHookEx($g_hMsgBoxHook)
    _WinAPI_UnhookWindowsHookEx($g_lPrevWnd)
    DllCallbackFree($g_SubMsgBox)
    DllCallbackFree($g_MsgProc)
    Alles anzeigen


    Kürzere Version angelehnt an funkey's Methode:

    AutoIt
    ;Coded by UEZ build 2023-04-29 beta
    
    #include <Timers.au3>
    #include <WinAPIConstants.au3>
    #include <WinAPIGdi.au3>
    #include <WinAPIProc.au3>
    #include <WinAPISys.au3>
    #include <WindowsConstants.au3>
    
    Const $HCBT_CREATEWND = 3, $HCBT_DESTROYWND = 4, $HCBT_ACTIVATE = 5, $g_iFlagDefault = BitOR($MB_TOPMOST, $MB_ICONINFORMATION)
    Global $g_hMsgBoxHook, $g_hSubMsgBox, $g_idTImer, $g_sBtn1_Txt = "Close", $g_sBtn2_Txt, $g_sBtn3_Txt
    Global $g_Timeout = 0
    
    Func _WinAPI_SetDlgItemText($hDlg, $nIDDlgItem, $lpString) ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setdlgitemtextw
        Local $aRet = DllCall("user32.dll", "int", "SetDlgItemText", "hwnd", $hDlg, "int", $nIDDlgItem, "str", $lpString)
        If @error Then Return SetError(@error, @extended, 0)
        Return $aRet[0]
    EndFunc   ;==>_WinAPI_SetDlgItemText
    
    Func _TimerProc($hwnd, $iMsg, $wParam, $lParam)
        If $g_Timeout <= 1 Then
            WinClose($hwnd)
        Else
            $g_Timeout -= 1
            _WinAPI_SetDlgItemText($hWnd, $IDOK + 1, $g_sBtn1_Txt & " [" & $g_Timeout & "]")
        EndIf
    EndFunc   ;==>_TimerProc
    
    Func _CBTHookProc($nCode, $wParam, $lParam)
        If $nCode < 0 Then Return _WinAPI_CallNextHookEx($g_hMsgBoxHook, $nCode, $wParam, $lParam)
        Local Const $hHWND = HWnd($wParam)
        Switch $nCode
            Case $HCBT_ACTIVATE
                If _WinAPI_GetClassName($hHWND) = "#32770" Then
                    If $g_Timeout Then $g_idTImer = _Timer_SetTimer($hHWND, 1000, "_TimerProc")
                    _WinAPI_SetDlgItemText($wParam, $IDOK, $g_Timeout ? $g_sBtn1_Txt & " [" & $g_Timeout & "]" : $g_sBtn1_Txt)
                EndIf
            Case $HCBT_DESTROYWND
                If _WinAPI_GetClassName($hHWND) = "#32770" Then _Timer_KillTimer($hHWND, $g_idTImer)
        EndSwitch
        Return _WinAPI_CallNextHookEx($g_hMsgBoxHook, $nCode, $wParam, $lParam)
    EndFunc   ;==>_CBTHookProc
    
    Func MsgBoxEx($sText, $sTitle = Default, $iTimeout = 0, $iFlag = Default, $sBtn_Txt = Default, $hParentHWND = "")
        If $sBtn_Txt <> Default Then $g_sBtn1_Txt = $sBtn_Txt
        If $iFlag = Default Then $iFlag = $g_iFlagDefault
        $g_Timeout = $iTimeout
        $g_MsgProc = DllCallbackRegister("_CBTHookProc", "int", "uint;wparam;lparam")
        Local Const $hThreadID = _WinAPI_GetCurrentThreadId()
        $g_hMsgBoxHook = _WinAPI_SetWindowsHookEx($WH_CBT, DllCallbackGetPtr($g_MsgProc), Null, $hThreadID)
        If $sTitle = Default Then $sTitle = "Information"
        Local Const $iReturn = MsgBox($iFlag, $sTitle, $sText, $iTimeout, $hParentHWND)
        _WinAPI_UnhookWindowsHookEx($g_hMsgBoxHook)
        DllCallbackFree($g_MsgProc)
        Return $iReturn
    EndFunc   ;==>MsgBoxEx
    
    ConsoleWrite(MsgBoxEx("This is a test", "Information", 5) & @CRLF)
    Alles anzeigen
  • MsgBox hooken und Countdown hinzufügen

    • UEZ
    • 26. April 2023 um 23:57

    Ich möchte gerne einen Countdown in das Ok Button hinzufügen, das die vorgebene Zeit herunter zählt. Man könnte dies natürlich mit einer eigen gebastelten GUI realisieren, aber will ich nicht. ;)

    Das habe ich soweit zusammen gebastelt, funktioniert leider nicht und meine Augen fallen gerade zu:

    AutoIt
    #include <WindowsConstants.au3>
    #include <WinAPIConstants.au3>
    #include <WinAPISys.au3>
    #include <WinAPIProc.au3>
    #include <Timers.au3>
    
    Global $tagCWPSTRUCT = "long lParam;long wParam;uint message;hwnd hwnd"
    Global $HCBT_ACTIVATE = 5, $g_hMsgBoxHook, $g_hMod, $g_hThreadID, $g_hSubMsgBox, $g_SubMsgBox, $g_lPrevWnd, $g_BtnID, $g_HWND, $g_idTImer
    Global $g_Time = 5
    
    Func _WinAPI_SetDlgItemText($hDlg, $nIDDlgItem, $lpString) ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setdlgitemtextw
        Local $aRet = DllCall("user32.dll", "int", "SetDlgItemText", "hwnd", $hDlg, "int", $nIDDlgItem, "str", $lpString)
        If @error Then Return SetError(@error, @extended, 0)
        Return $aRet[0]
    EndFunc   ;==>_WinAPI_SetDlgItemText
    
    Func _SubMsgBoxProc($hwnd, $iMsg, $wParam, $lParam)
        Switch $iMsg
            Case $WM_SHOWWINDOW
            Case $WM_TIMER
                _WinAPI_SetDlgItemText($g_BtnID, $IDOK, "OK [" & $g_Time & "]")
                $g_Time -= 1
                If $g_Time < 0 Then
                    _Timer_KillTimer($g_idTImer, $g_HWND)
                    _WinAPI_SetWindowLong($hwnd, $GWL_WNDPROC, $g_lPrevWnd)
                EndIf
                Return 0
            Case $WM_DESTROY
                _Timer_KillTimer($g_idTImer, $g_HWND)
                ;_WinAPI_SetWindowLong($hwnd, $GWL_WNDPROC, $g_lPrevWnd)
        EndSwitch
        Return _WinAPI_CallWindowProc($g_lPrevWnd, $hWnd, $iMsg, $wParam, $lParam)
    EndFunc
    
    Func _CBTHookProc($nCode, $wParam, $lParam)
        If $nCode < 0 Then Return _WinAPI_CallNextHookEx($g_hMsgBoxHook, $nCode, $wParam, $lParam)
        Local $tCWP = DllStructCreate($tagCWPSTRUCT, $lParam)
        Switch $nCode
            Case $HCBT_ACTIVATE
                $g_HWND = HWnd($wParam)
                If _WinAPI_GetClassName($g_HWND) = "#32770" Then
                    $g_idTImer = _Timer_SetTimer($g_HWND, 1000)
                    $g_BtnID = HWnd($wParam) ;_WinAPI_GetDlgItem($wParam, 1)
                    _WinAPI_SetDlgItemText($g_BtnID, $IDOK, "OK [" & $g_Time & "]")
                    $g_lPrevWnd = _WinAPI_SetWindowLong($g_HWND, $GWL_WNDPROC, DllCallbackGetPtr($g_SubMsgBox))
                EndIf
        EndSwitch
        Return _WinAPI_CallNextHookEx($g_hMsgBoxHook, $nCode, $wParam, $lParam)
    EndFunc
    
    
    $g_SubMsgBox = DllCallbackRegister("_SubMsgBoxProc", "long", "hwnd;uint;wparam;lparam")
    $g_MsgProc = DllCallbackRegister("_CBTHookProc", "int", "uint;wparam;lparam")
    $g_hMod = _WinAPI_GetModuleHandle(0)
    $g_hThreadID = _WinAPI_GetCurrentThreadId()
    $g_hMsgBoxHook = _WinAPI_SetWindowsHookEx($WH_CBT, DllCallbackGetPtr($g_MsgProc), Null, $g_hThreadID)
    MsgBox(0, "Test", "This is a test message box!")
    _WinAPI_UnhookWindowsHookEx($g_hMsgBoxHook)
    _WinAPI_UnhookWindowsHookEx($g_lPrevWnd)
    DllCallbackFree($g_SubMsgBox)
    DllCallbackFree($g_MsgProc)
    Alles anzeigen

    Könnt ihr den Fehler sehen?

    :sleeping:

  • Farben Sortieren / Gruppieren

    • UEZ
    • 7. April 2023 um 13:15

    Vielen Dank fee

    Ich werde mir das mal anschauen, ob ich eine Sortierung sehen kann. Momentan ist das Thema bei mir ein wenig eingeschlafen.

    Falls interesse besteht, habe ich die Farbraumumwandelfunktionen nach Freebasic portiert: Color space / difference / distance converter


    Die aktuelle Version: ColorSorterGrouper.au3

    Colors.png

  • Screenshot - Bereich per Maus auswählen

    • UEZ
    • 28. März 2023 um 21:40

    Andy danke.

    Anscheinend darf man kein https// vor die Adresse einfügen, da ansonsten die Forum Software nochmals ein https:// davor setzt. Der Link sollte jetzt funzen.

    SOLVE-SMART Danke für den Hinweis.

  • Screenshot - Bereich per Maus auswählen

    • UEZ
    • 28. März 2023 um 16:06

    Ich hatte auch mal was in die Richtung gebastelt: _WinAPI_MarkScreenRegionAndCapture 0.92 build 2017-01-22

    Vielleicht nützlich für dein Anliegen...

  • Farben Sortieren / Gruppieren

    • UEZ
    • 18. März 2023 um 21:16

    eukalyptus das Resultat sieht echt gut aus! :thumbup:

    Ich habe mal an CIEDE2000 versucht, läuft aber irgendwie nicht wirklich.

    AutoIt
    #include <Array.au3>
    
    Const $pow25To7 = 6103515625.0, $16d116 = 16 / 116, $1d3 = 1 / 3
    Const $PI = ACos(-1)
    Const $deg360InRad = deg2Rad(360.0), $deg180InRad = deg2Rad(180.0)
    
    Func Min($a, $b)
        Return ($a < $b) ? $a : $b
    EndFunc
    
    Func Max($a, $b)
        Return ($a > $b) ? $a : $b
    EndFunc
    
    Func ATan2($y, $x)
        Local $result = Atan($y / $x)
        If $x < 0 Then
            $result += $PI
        ElseIf $y < 0 Then
            $result += 2 * $PI
        EndIf
        Return $result
    EndFunc
    
    Func deg2Rad(Const $deg)
        Return ($deg * ($PI / 180.0))
    EndFunc
    
    Func rad2Deg(Const $rad)
        Return ((180.0 / $PI) * $rad)
    EndFunc
    
    Func Pow($a, $b)
        Return $a ^ $b
    EndFunc
    
    Func _ColorRGB($R, $G, $B)
        Return BitOR(0xFF000000, BitShift($R, -16), BitShift($G, -8), $b)
    EndFunc
    
    ;--------------------------------------------------------------------------------------------
    Func CIEDE2000($Lab1, $Lab2) ;http://en.wikipedia.org/wiki/Color_difference#CIEDE2000)
        Local $lab1l = $Lab1[0], $lab1a = $Lab1[1], $lab1b = $Lab1[2], _
              $lab2l = $Lab2[0], $lab2a = $Lab2[1], $lab2b = $Lab1[2], _
              $k_L = 1.0, $k_C = 1.0, $k_H = 1.0
    
        ;step1
        ;Equation 2
        Local $C1 = Sqrt(($lab1a * $lab1a) + ($lab1b * $lab1b))
        Local $C2 = Sqrt(($lab2a * $lab2a) + ($lab2b * $lab2b))
        ;Equation 3
        Local $barC = ($C1 + $C2) / 2.0
        ;Equation 4
        Local $G = 0.5 * (1 - Sqrt(Pow($barC, 7) / (Pow($barC, 7) + $pow25To7)))
        ;Equation 5
        Local $a1Prime = (1.0 + $G) * $lab1a
        Local $a2Prime = (1.0 + $G) * $lab2a
        ;Equation 6
        Local $CPrime1 = Sqrt(($a1Prime * $a1Prime) + ($lab1b * $lab1b))
        Local $CPrime2 = Sqrt(($a2Prime * $a2Prime) + ($lab2b * $lab2b))
        ;Equation 7
        Local $hPrime1
        If $lab1b = 0 And $a1Prime = 0 Then
            $hPrime1 = 0
        Else
            $hPrime1 = Atan2($lab1b, $a1Prime)
            ;This must be converted to a hue angle in degrees between 0
            ;and 360 by addition of 2pi to negative hue angles.
            If $hPrime1 < 0 Then $hPrime1 += $deg360InRad
        EndIf
        Local $hPrime2
        If $lab2b = 0 And $lab2b = 0 Then
            $hPrime2 = 0
        Else
            $hPrime2 = Atan2($lab2b, $a2Prime)
            ;This must be converted to a hue angle in degrees between 0
            ;and 360 by addition of 2pi to negative hue angles.
            If ($hPrime2 < 0) Then $hPrime2 += $deg360InRad
        EndIf
    
        ;step2
        ;Equation 8
        Local $deltaLPrime = $lab2l - $lab1l
        ;Equation 9
        Local $deltaCPrime = $CPrime2 - $CPrime1
        ;Equation 10
        Local $deltahPrime
        Local $CPrimeProduct = $CPrime1 * $CPrime2
        If $CPrimeProduct = 0 Then
            $deltahPrime = 0
        Else
            ;Avoid the fabs() call
            $deltahPrime = $hPrime2 - $hPrime1
            If ($deltahPrime < -$deg180InRad) Then
                $deltahPrime += $deg360InRad
            ElseIf $deltahPrime > $deg180InRad Then
                $deltahPrime -= $deg360InRad
            EndIf
        EndIf
        ;Equation 11
        Local $deltaHPrime2 = 2.0 * Sqrt($CPrimeProduct) * Sin($deltahPrime / 2.0)
    
        ;step3
        ;Equation 12
        Local $barLPrime = ($lab1l + $lab2l) / 2.0
        ;Equation 13
        Local $barCPrime = ($CPrime1 + $CPrime2) / 2.0
        ;Equation 14
        Local $barhPrime, $hPrimeSum = $hPrime1 + $hPrime2
        If ($CPrime1 * $CPrime2 = 0) Then
            $barhPrime = $hPrimeSum
        Else
            If (Abs($hPrime1 - $hPrime2) <= $deg180InRad) Then
                $barhPrime = $hPrimeSum / 2.0
            Else
                If ($hPrimeSum < $deg360InRad) Then
                    $barhPrime = ($hPrimeSum + $deg360InRad) / 2.0
                Else
                    $barhPrime = ($hPrimeSum - $deg360InRad) / 2.0
                EndIf
            EndIf
        EndIf
        ;Equation 15
        Local $T = 1.0 - (0.17 * Cos($barhPrime - deg2Rad(30.0))) + _
                  (0.24 * Cos(2.0 * $barhPrime)) + _
                  (0.32 * Cos((3.0 * $barhPrime) + deg2Rad(6.0))) -  _
                  (0.20 * Cos((4.0 * $barhPrime) - deg2Rad(63.0)))
        ;Equation 16
        Local $deltaTheta = deg2Rad(30.0) * Exp(-Pow(($barhPrime - deg2Rad(275.0)) / deg2Rad(25.0), 2.0))
        ;Equation 17
        Local $R_C = 2.0 * Sqrt(Pow($barCPrime, 7.0) / (Pow($barCPrime, 7.0) + $pow25To7))
        ;Equation 18
        Local $S_L = 1 + ((0.015 * Pow($barLPrime - 50.0, 2.0)) / Sqrt(20 + Pow($barLPrime - 50.0, 2.0)))
        ;Equation 19
        Local $S_C = 1 + (0.045 * $barCPrime)
        ;Equation 20
        Local $S_H = 1 + (0.015 * $barCPrime * $T)
        ;Equation 21
        Local $R_T = (-Sin(2.0 * $deltaTheta)) * $R_C
        ;Equation 22
        Local $deltaE = Sqrt( _
                                Pow($deltaLPrime / ($k_L * $S_L), 2.0) + _
                                Pow($deltaCPrime / ($k_C * $S_C), 2.0) + _
                                Pow($deltaHPrime2 / ($k_H * $S_H), 2.0) + _
                                ($R_T * ($deltaCPrime / ($k_C * $S_C)) * ($deltaHPrime2 / ($k_H * $S_H))))
        Return $deltaE
    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 RGB2LAB($iRGB)
        Local $r = BitAND(BitShift($iRGB, 16), 0xFF) / 255, _
              $g = BitAND(BitShift($iRGB, 8), 0xFF) / 255, _
              $b = BitAND($iRGB, 0xFF) / 255
    
              $r = ($r > 0.04045) ? Pow(($r + 0.055) / 1.055, 2.4) : $r / 12.92
              $g = ($g > 0.04045) ? Pow(($g + 0.055) / 1.055, 2.4) : $g / 12.92
              $b = ($b > 0.04045) ? Pow(($b + 0.055) / 1.055, 2.4) : $b / 12.92
    
              $x = ($r * 0.4124 + $g * 0.3576 + $b * 0.1805) / 0.95047
              $y = ($r * 0.2126 + $g * 0.7152 + $b * 0.0722) / 1.00000
              $z = ($r * 0.0193 + $g * 0.1192 + $b * 0.9505) / 1.08883
    
              $x = ($x > 0.008856) ? Pow($x, $1d3) : (7.787 * $x) + $16d116
              $y = ($y > 0.008856) ? Pow($y, $1d3) : (7.787 * $y) + $16d116
              $z = ($z > 0.008856) ? Pow($z, $1d3) : (7.787 * $z) + $16d116
    
        Local $aLAB[3] = [(116 * $y) - 16, 500 * ($x - $y), 200 * ($y - $z)]
        Return $aLAB
    EndFunc
    
    Func LAB2RGB($lab)
        Local $y = ($lab[0] + 16) / 116, $x = $lab[1] / 500 + $y, $z = $y - $lab[2] / 200, $r, $g, $b
        $x = 0.95047 * (($x * $x * $x > 0.008856) ? $x * $x * $x : ($x - 16/116) / 7.787)
        $y = 1.00000 * (($y * $y * $y > 0.008856) ? $y * $y * $y : ($y - 16/116) / 7.787)
        $z = 1.08883 * (($z * $z * $z > 0.008856) ? $z * $z * $z : ($z - 16/116) / 7.787)
    
        $r = $x *  3.2406 + $y * -1.5372 + $z * -0.4986
        $g = $x * -0.9689 + $y *  1.8758 + $z *  0.0415
        $b = $x *  0.0557 + $y * -0.2040 + $z *  1.0570
    
        $r = ($r > 0.0031308) ? (1.055 * Pow($r, 1/2.4) - 0.055) : 12.92 * $r
        $g = ($g > 0.0031308) ? (1.055 * Pow($g, 1/2.4) - 0.055) : 12.92 * $g
        $b = ($b > 0.0031308) ? (1.055 * Pow($b, 1/2.4) - 0.055) : 12.92 * $b
        Return _ColorRGB(Max(0, Min(1, $r)) * 255, Max(0, Min(1, $g)) * 255, Max(0, Min(1, $b)) * 255)
    EndFunc
    
    
    ; Calculate the color difference between two colors in L*a*b* space
    Func ColorDifference($lab1, $lab2)
        Local $dE = 0
        ; calculate the differences in L*, a*, and b* components
        Local $dL = Abs(($lab1[0]) - ($lab2[0]))
        Local $da = Abs(($lab1[1]) - ($lab2[1]))
        Local $db = Abs(($lab1[2]) - ($lab2[2]))
        ; calculate the chroma and hue differences
        Local $dC = Sqrt($da^2 + $db^2)
        Local $dH = Sqrt($dL^2 + $dC^2)
        ; calculate the weighting factors
        Local $SL = $lab1[0] + $lab2[0]
        Local $SC = $dC + Sqrt($lab1[1]^2 + $lab1[2]^2) + Sqrt($lab2[1]^2 + $lab2[2]^2)
        Local $SH = Sqrt($lab1[1]^2 + $lab1[2]^2) + Sqrt($lab2[1]^2 + $lab2[2]^2) + $dC
        Local $fL = 1 - 0.5 * ($SL - 50)^2 / (50^2 + 0.000001)
        Local $fC = 0.5 * (1 + $SC / ($SC + 0.000001))
        Local $fH = 0.5 * (1 + $SH / ($SH + 0.000001))
        ; calculate the CIEDE2000 color difference
        If $dH <= 1 And $dC <= 1 Then
            $dE = Sqrt($dL^2 + $dC^2 + $dH^2)
        Else
            $dE = Sqrt($dL^2 + ($fC * $dC)^2 + ($fH * $dH)^2)
        EndIf
        Return $dE
    EndFunc
    
    
    Global $aColors[] = [0xFF0018, 0x0095FF, 0xEFEFEF, 0x000000, 0xFDEA00], $LABColors[UBound($aColors)]
    Global $i, $temp, $differences[UBound($aColors)][UBound($aColors)], $sums[UBound($aColors)][2], $sortedColors[UBound($aColors)]
    
    ; convert the hex colors to L*a*b* colors
    For $i = 0 To UBound($aColors) - 1
        $LABColors[$i] = RGB2LAB($aColors[$i])
    Next
    
    ; calculate the color differences between each pair of colors
    For $i = 0 To UBound($aColors) - 2
        For $j = $i + 1 To UBound($aColors) - 1
            $differences[$i][$j] = CIEDE2000($LABColors[$i], $LABColors[$j])
            $differences[$j][$i] = $differences[$i][$j]
        Next
    Next
    
    ; sort the colors based on the sum of their color differences with the other colors
    For $i = 0 To UBound($aColors) - 1
        $sums[$i][0] = 0
        $sums[$i][1] = $aColors[$i]
        For $j = 0 To UBound($aColors) - 1
            If $i <> $j Then
                $sums[$i][0] += $differences[$i][$j]
            EndIf
        Next
    Next
    _ArraySort($sums)
    
    ; reorder the colors based on the sorted sums
    For $i = 0 To UBound($LABColors) - 1
        $sortedColors[$i] = $sums[$i][1]
    Next
    
    Global $aSoll[] = ["0xEFEFEF", "0xFDEA00", "0x0095FF", "0xFF0018", "0x000000"]
    
    ; display result
    ConsoleWrite("Color" & @TAB & "Sort." & @TAB & "Soll" & @CRLF)
    
    For $i = 0 To UBound($LABColors) - 1
        ConsoleWrite(Hex($aColors[$i], 6) & @TAB & Hex($sortedColors[$i], 6) & @TAB & $aSoll[$i] & @CRLF)
    Next
    Alles anzeigen

    Vielleicht sieht jemand den Fehler...

    RGB2LAB / LAB2RGB sind von einem JS portiert zwecks Test. Output von eukalyptus' RGB2LAB Version ist identisch :!:

  • Farben Sortieren / Gruppieren

    • UEZ
    • 18. März 2023 um 15:51

    fee danke für deinen Beitrag! :thumbup:

    Das Resultat von SortByBrightColor ist besser als das von SortByLum, was ähnlich ist.

    Die Seite von Elektrobild habe ich auch gesehen, aber ist kein Code veröffentlicht. Ich habe im Source Code geschaut, aber nicht den Code momentan noch nicht entdeckt.

    Danke.

  • Farben Sortieren / Gruppieren

    • UEZ
    • 15. März 2023 um 21:55

    Mars das Resultat gefällt mir :thumbup:

    So siehts momentan mit zufälligen Farben aus:

    Resultat.png

    So sieht es bei der Farbtabelle von Andy aus:

    Resultat2.png

    Der aktuelle Code dazu:

    AutoIt
    ;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, 480)
    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() * 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")
    
    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(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 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

    Ich weiß nicht, warum hier die Gruppierung nicht ganz passt. Bei der Gruppierung werden 12 + 1 Gruppen erstellt. Das +1 sind die Graustufen.

  • Farben Sortieren / Gruppieren

    • UEZ
    • 15. März 2023 um 10:40

    @Bugix: danke für die Info.

    Ich habe was in Freebasic geschrieben, um einfach die WinAPI besser zu lernen, da man in FB nicht den Luxus der UDFs hat. :)

    Color_Constants.png

    Ich habe nun die Farbtabelle erweitert und dabei ist mir aufgefallen, dass die Farben nicht mehr "so schön" angezeigt werden. Daher der Ansatz die Farben entsprechend darzustellen.

  • Farben Sortieren / Gruppieren

    • UEZ
    • 15. März 2023 um 09:27
    Zitat von SOLVE-SMART

    Ist die Pixelbreite der einzelnen Farbe bzw. die Darstellung, abhängig von der Gesamtbreite der GUI? Also falls die einzelne Farbe ein Pixel breit sein sollte, skaliert diese Breite bei resize der GUI? Ich habe mir den Code nicht genau angeschaut, muss ich zugeben. Vielleicht könnte ich es auch dort erfassen - sind nun aber nicht gerade nur 50 Zeilen Code, daher frage ich lieber direkt UEZ.

    Es werden zufällig 512 Farben generiert, sortiert und dargestellt. D.h. der Farbbalken ist 512 Pixel breit und 32 Pixel hoch. Die GUI wird nicht automatisch angepasst, sondern ist manuell angepasst.


    Zitat von Peter S. Taler

    ich finde das mit den "fragmentierten Farbgruppen" nicht schlimm. Im Gegenteil, Es hilft, zumindest mir, sich besser zu orientieren.

    Ist ja auch nicht schlimm, sondern, je nach Fall, besser oder schlechter.


    Zitat von eukalyptus

    Eine Idee wäre, zuerst in HSL zu gruppieren u innerhalb mit LAB zu sortieren...

    Die Idee hatte ich auch. Ich habe noch nach der Pixeldistanz innerhalb der Gruppe sortieren lassen. Hier das Resultat:

    Resultat.png

    Code;

    AutoIt
    ;Coded by UEZ build 2023-03-15
    #include <Array.au3>
    #include <GDIPlus.au3>
    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>
    _GDIPlus_Startup()
    
    Global $hGUI = GUICreate("GDI+ Color Sorting / Grouping Test", 800, 320)
    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")
    
    SortByLAB($aColortable)
    $y += 40
    DrawColors($y, "LAB")
    
    _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 SortByLAB(ByRef $aColortable, $iStartRGB = 0xFF0000) ;by eukalyptus
        Local $iDim = UBound($aColortable), $iDim2 = UBound($aColortable, 2)
        Local $aLAB[$iDim][2], $i
    
        For $i = 0 To $iDim - 1
            $aLAB[$i][0] = $iDim2 ? _RGB2LAB($aColortable[$i][0]) : _RGB2LAB($aColortable[$i])
        Next
    
        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)
        Local $i, $aTmp[2], $swapped
        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
    EndFunc
    
    Func SortByHSL(ByRef $aColortable, $sc = 1)
        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]
            $aColortable2[$i][2] = $a[1]
            $aColortable2[$i][3] = $a[2]
            $aColortable2[$i][4] = 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 = 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, $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)
                SortByDistance($orange)
                SortByDistance($yellow)
                SortByDistance($lime)
                SortByDistance($green)
                SortByDistance($turqoise)
                SortByDistance($cyan)
                SortByDistance($cobalt)
                SortByDistance($blue)
                SortByDistance($violet)
                SortByDistance($magenta)
                SortByDistance($magenta)
                SortByDistance($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 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)
                SortByDistance($orange)
                SortByDistance($yellow)
                SortByDistance($lime)
                SortByDistance($green)
                SortByDistance($turqoise)
                SortByDistance($cyan)
                SortByDistance($cobalt)
                SortByDistance($blue)
                SortByDistance($violet)
                SortByDistance($magenta)
                SortByDistance($magenta)
                SortByDistance($grey)
            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($magenta)
                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 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

    Da gibt es noch Hilbert-Sort. Mal sehen, ob das Result anders wird...

  • Farben Sortieren / Gruppieren

    • UEZ
    • 14. März 2023 um 22:22

    Hi eukalyptus,

    lange nichts mehr von dir "gehört". :)

    Danke für LAB Code, sieht sehr homogen aus, nur sind die Farbgruppen relativ fragmentiert.

    Resultat.png

  • Farben Sortieren / Gruppieren

    • UEZ
    • 14. März 2023 um 15:38

    Ich habe ein kleines Tool geschrieben, das eine Textdatei einliest (<Name der Farbe;Hex Code>) und sie in einer Listview farbig darstellt. Manchmal suche ich nach einer bestimmten Farbe und wenn die Liste unsortiert ist, dann ist das nicht so optimal, um die Farbe zu finden.

    Außerdem ist das ein interessantes Thema . ;)

  • Farben Sortieren / Gruppieren

    • UEZ
    • 14. März 2023 um 14:22

    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

    Resultat.png

    Die Ergebnisse sehen ganz passable aus, aber noch nicht gut genug, da man immer noch Farbfragmente innerhalb der Farbbereiche sieht.

    Habt ihr noch Ideen?

Spenden

Jeder Euro hilft uns, Euch zu helfen.

Download

AutoIt Tutorial
AutoIt Buch
Onlinehilfe
AutoIt Entwickler
  1. Datenschutzerklärung
  2. Impressum
  3. Shoutbox-Archiv
Community-Software: WoltLab Suite™