Neuigkeiten:

Ist euer Problem gelöst, dann bitte den Knopf "Thema gelöst" drücken!

Mobiles Hauptmenü

Dunkelheit eines Farbwertes

Begonnen von Hondo, Dezember 12, 2019, 22:03:20

⏪ vorheriges - nächstes ⏩

Hondo

Hallo,
ist bestimmt ein seltsamer Betreff, aber genau darum geht es.
Zur Darstellung von Farbwerten mit Ihren Farben möchte ich ab einer gewissen Dunkelheit einer Farbe die Textfarbe eines Textfeldes von Schwarz auf Weiß umschalten.
Gibts dazu ein bekannter Algorithmus?
Beispiel ist z.B. das Programm ColorPic wenn das jemand kennt.
Gruß Andreas

daolix

Hallo
so auf die schnelle denke ich die Apis ColorRGBToHLS/ColorHLSToRGB mit Auswertung der Luminance könnten das sein was du suchst.

Hondo

Hallo,
hilft mir leider nur bedingt weiter.
z.B. hat reines Blau eine lightness von 0,5, ebenso wie reines Grün oder Rot.
Aber das Grün ist im Verhältnis zum Blau doch viel heller.
Ich bräuchte einen Algorithmus der nicht nur die lightness sondern auch woher aus welcher Farbe diese entsteht.
Gruß Andreas

daolix

Aha. Na dann hab ich dein prob doch nicht so richtig verstanden. Aber hier mal Consts die ich eigentlich zur Staturationberechnung in gdip verwendet hatte.
die dann mit den entsprechenden Farbbytes deiner Farbe multiplizieren und aufsummieren
Const lumR = 0.3086
Const lumG = 0.6094
Const lumB = 0.082
Ab welchen Wert du dann switchen tust must du dann festlegen.

Hondo

Hallo,
hab es auch mit dem HSV-Farbraum versucht - ohne Ergebnisse.
Deine Konstanten verstehe ich nicht ganz. 0.082 Blau soll was für eine Schwelle sein? ist ja ganz wenig Blau nur.
Hast du dazu ein paar Zeilen Code?
Gruß Andreas

daolix

ich dachte an sowas:
Type tl
    l As Long
End Type

Type tc
    r As Byte
    g As Byte
    b As Byte
    a As Byte
End Type


Function KeineAhnungObDunkel(ByVal DieRGBFarbe As Long) As Single
    Dim tl As tl, tc As tc
    tl.l = DieRGBFarbe
    LSet tc = tl
    Const lumR = 0.3086
    Const lumG = 0.6094
    Const lumB = 0.082
    With tc
        KeineAhnungObDunkel = .r * lumR + .g * lumG + .b * lumB
    End With
End Function

Hondo

Hallo,
ich hab jetzt sowas ähnliches wie eine Lösung gefunden:


        With rCell
            .Offset(0, 3).Interior.Color = RGB(.Value, .Offset(0, 1).Value, .Offset(0, 2).Value)
        End With

        If (rCell.Value < 150 And rCell.Offset(0, 1).Value < 150 And rCell.Offset(0, 2).Value < 150) Or _
           ((rCell.Value + rCell.Offset(0, 1).Value + rCell.Offset(0, 2).Value) < 250) Or _
           Not ((rCell.Value > 200 Or rCell.Offset(0, 1).Value > 200 Or rCell.Offset(0, 2).Value > 200)) Then
            rCell.Offset(0, 3).Font.Color = -2   ' white
            rCell.Offset(0, 4).Value = 1
        Else
            rCell.Offset(0, 3).Font.Color = -1   ' black
            rCell.Offset(0, 4).Value = 0
        End If


Stammt von dieser Webseite her:
https://gallery.technet.microsoft.com/Excel-list-of-colour-names-8092dc89

Obiger Code ist die Berechnung eines Wertes namens Obverse (0 oder 1), wobei der/die Autor(en) dazu folgendes noch schreiben: Column F is a value to indicate whether the obverse colour should be dark or light. Indicate by 0 or 1. This was based on Lightness, but some values were manually tweaked.

Vorallem der letzte Halbsatz ist interessant.
Setze das mal in meinem Projekt um und teste ob es brauchbar ist.
Gruß Andreas

Hondo

OK, funktioniert.
Hab es noch etwas verfeinert:

Public Sub is2Dark(ByVal lRed As Long, ByVal lGreen As Long, ByVal lBlue As Long, ByRef ctlTXT As Access.TextBox)
    If (lRed < 150 And lGreen < 150 And lBlue < 150) Or _
        ((lRed + lGreen + lBlue) < 250) Or _
        Not ((lRed > 200 Or lGreen > 200 Or lBlue > 200)) Or _
        (lRed < 50 And lGreen < 150 And lBlue > 200) Or _
        (lRed < 80 And lGreen < 150 And lBlue > 240) Then
        ctlTXT.ForeColor = 16777215
    Else
        ctlTXT.ForeColor = 0
    End If
End Sub


Gruß Andreas

daolix

ja kann machen, insbesondere wenn man bestimmte Farbbereiche definiert behandeln will, mir hingegen würde nur ein definierter Schwellenwert ( hier 170 was ca. 2/3 von 255 sind )  reichen. Letzlich gehts ja nur um die Lesbarkeit.
Sub KeineAhnungObDunkel(ByVal lRed As Long, ByVal lGreen As Long, ByVal lBlue As Long, ByRef ctlTXT As Access.TextBox)
    If lRed * 0.3086 + lGreen * 0.6094 + lBlue * 0.082 < 170 Then
        ctlTXT.ForeColor = 16777215
    Else
        ctlTXT.ForeColor = 0
    End If
End Sub