Dominierende Farbe in Bitmap berechnen

  • Hallo zusammen,

    weiß jemand, wie man schnell und einfach die am häufigsten verwendete Farbe in einer Bitmap berechnen kann?
    Gibt es eventuell eine UDF dazu?

    Grüße ErrorKid

  • Wenn mit Bitmap, das Bitmap-Dateiformat gemeint ist:

    Nunja. Ich weiß nicht ob es dafür eine UDF gibt, aber BMPs sind einfach zu bearbeiten.

    Du kannst den Header wegschneiden und dann mit String-Operationen einfach die Häufigkeit in den Pixeln messen. Um die entsprechende Farbe zu bekommen, vergleichst du dann das Ergebnis (die häufigste Farbe) mit der Farbtabelle (zwischen Header und Pixeln)

    Einfach alle Farben durchlaufen zu lassen wäre extrem langsam, durch die Farb-Lookup-Tabelle in der BMP wird das alles etwas einfacher.

  • Um genau zu sein handelt es sich um ein Bitmap-Objekt erzeugt durch

    [autoit]


    $hBitmapScreen = _ScreenCapture_CaptureWnd("",$hwnd)
    $hBitmapScreen = _GDIPlus_BitmapCreateFromHBITMAP($hBitmapScreen)

    [/autoit]

    Meine Frage ist eher wie ich da eben schnell die meist genutzte Farbe heraus finden kann.
    Also nicht der Durchschnitt aller Pixel sondern wirklich die Farbe, welche am meisten genutzt wird ;)

  • Alles klar, wenn du mir für diesen Absatz:

    Zitat

    Du kannst den Header wegschneiden und dann mit String-Operationen einfach die Häufigkeit in den Pixeln messen. Um die entsprechende Farbe zu bekommen, vergleichst du dann das Ergebnis (die häufigste Farbe) mit der Farbtabelle (zwischen Header und Pixeln)

    einen ungefähren Programieransatz geben kannst wäre es perfekt. Hab mit sowas nämlich noch nicht mal ansatzweiße etwas zu tun gehabt :D

  • Hat noch jemand eine Idee wie ich folgende Funktion noch beschleunigen kann?


    [autoit]


    Func _BitmapGetAverageColor($hBitmap, $Step = 0) ;Average = Durchschnitt - ich weiß ;)
    $height = _GDIPlus_ImageGetHeight($hBitmap)
    $width = _GDIPlus_ImageGetWidth($hBitmap)

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    $steps = 0
    For $y = 1 To $height Step $Step ;ginge bestimmt anders, war mich aber zu viel Arbeit ^^
    For $x = 1 To $width Step $Step
    $steps += 1
    Next
    Next

    [/autoit][autoit][/autoit][autoit]

    Dim $Colors[$steps]

    [/autoit][autoit][/autoit][autoit]

    $index = 0
    For $y = 1 To $height Step $Step
    For $x = 1 To $width Step $Step
    $pixelcolor = _GDIPlus_BitmapGetPixel($hBitmap, $x, $y)
    $Colors[$index] = $pixelcolor
    $index += 1
    Next
    Next

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    Dim $AllColorInformation[UBound($Colors)][2]
    $indexTwo = 0
    For $indexOne = 0 To UBound($Colors) - 1
    $ValueToCheck = $Colors[$indexOne]
    $Found = _ArraySearch($AllColorInformation, $ValueToCheck)
    If $Found <> -1 Then
    $AllColorInformation[$Found][1] += 1
    If $AllColorInformation[$Found][1] > UBound($Colors) - 1 - $indexOne Then ExitLoop
    Else
    $AllColorInformation[$indexTwo][0] = $Colors[$indexOne]
    $AllColorInformation[$indexTwo][1] = 1
    $indexTwo += 1
    EndIf
    Next
    _ArraySort($AllColorInformation, 1, 0, 0, 1)
    Return $AllColorInformation[0][0]
    EndFunc

    [/autoit]
  • Wäre ein 2D-Array nicht viel sinnvoller?
    Und für sowas eine For-Schleife zu benutzen... Das lässt sich mit Grundschul-Mathematik lösen. 8|

    [autoit]


    For $Y = 1 To $height Step $step
    For $X = 1 To $width Step $step

    [/autoit]


    Bei Step 1 wären das insgesamt $height * $width Durchläufe...
    Sonst gilt: Durchläufe = ($height * $width) / $step
    Bzw:

    [autoit]


    $steps = ($height * $width) / $step

    [/autoit]

    Selbes Prinzip bei den anderen Schleifen...

    chess


  • Und für sowas eine For-Schleife zu benutzen... Das lässt sich mit Grundschul-Mathematik lösen. 8|

    Erstaunlicher weiße nicht :D
    Bei

    [autoit]

    ($height*$width)/$Step

    [/autoit]


    Bekomme ich den Wert 43767,5 anstatt 1505. Wenn ich

    [autoit]

    ($height/$Step)*($width/$Step)

    [/autoit]


    rechne - was meiner Meinung nach eigentlich richtig sein sollte - bekomme ich 1458,91 raus.
    Ich weiß nicht genau wie die Step-Anweisung damit um geht wenn der Wert nicht ordentlich geteilt werden kann, deswegen habe ich auch die For-Schleife benutzt. Unnötig ohne ende aber immerhin bekomme ich den Wert zurück, der auch richtig ist.

    Mal ganz abgesehen davon wie unnötig es ist, dauert die ganze Aktion 0,35ms. Nicht der Performanceboost den ich mir erwünscht habe :P



    Wäre ein 2D-Array nicht viel sinnvoller?


    Richtig, das verwende ich auch: $AllColorInformation

  • Soll das Programm die Farben sozusagen mischen oder wirklich die einzelne Farbe (z.B. 0xFFFFABFF) ausgeben die am häufigsten verwendet wird. Oder soll das das ganze z.B. Rot Grün oder Blau ausgeben?