ANN: Auf jeden Fall sichtbare Farbe

06/10/2007 - 11:35 von Karsten Sosna | Report spam
Hallo NG,
des öfteren wurde schon gefragt wie man eine Farbe "umkehrt". Dann wird
meißtens auf ein XOR-Verknüpfung hingewiesen. Dass das bei Grau nicht
besonders gut funktioniert sollte einleuchten.
Ich habe nun eine relative einfache Möglichkeit gefunden, wie man eine Farbe
erzeugt die auf einer anderen auf jeden Fall sichtbar ist. Hierzu wandelt
man erstmal die Farbe von RGB-Farbraum in den HSV-Farbraum um. Nun addiert
man bspw. 0.5 zur Dunkelstufe(Value) und verrechnet den neuen Wert mit
Modulo 1. Zum Schluß braucht man den HSV-Wert nur wieder in den RGB-Farbraum
überführen.
Beispiel:
\\\
Dim c As Color = Color.CadetBlue
Dim hsv As HSV = RGB2HSV(c)
hsv.V = (hsv.V + 0.5) Mod 1
c = HSV2RGB(hsv)
'...
Public Structure HSV
Public H As Double
Public S As Double
Public V As Double
End Structure

Public Shared Function RGB2HSV(ByVal color As Color) As HSV
Dim retValue As HSV
Dim r As Double = color.R / 255
Dim g As Double = color.G / 255
Dim b As Double = color.B / 255
Dim max As Double = Math.Max(Math.Max(r, g), b)
Dim min As Double = Math.Min(Math.Min(r, g), b)
Dim delta As Double = max - min

Select Case max
Case min
retValue.H = 0
Case r
retValue.H = (g - b) / delta * 60
Case g
retValue.H = (2 + (b - r) / delta) * 60
Case b
retValue.H = (4 + (r - g) / delta) * 60
End Select

If retValue.H < 0 Then
retValue.H += 360
End If
If max = 0 Then
retValue.S = 0
Else
retValue.S = (max - min) / max
End If
retValue.V = max
Return retValue
End Function

Public Shared Function HSV2RGB(ByVal hsv As HSV) As Color
Dim retValue As Color
hsv.H = hsv.H Mod 360
If hsv.S = 0 Then
retValue = Color.FromArgb(CByte(hsv.V * 255), CByte(hsv.V * 255),
CByte(hsv.V * 255))
Else
hsv.H = hsv.H / 60
Dim i As Byte = CByte(Math.Floor(hsv.H))
Dim f As Byte = CByte(hsv.H - i)
Dim p As Byte = CByte(hsv.V * (1 - hsv.S) * 255)
Dim q As Byte = CByte(hsv.V * (1 - hsv.S * f) * 255)
Dim t As Byte = CByte(hsv.V * (1 - hsv.S * (1 - f)) * 255)
Select Case i
Case 0
retValue = Color.FromArgb(CByte(hsv.V * 255), t, p)
Case 1
retValue = Color.FromArgb(q, CByte(hsv.V * 255), p)
Case 2
retValue = Color.FromArgb(p, CByte(hsv.V * 255), t)
Case 3
retValue = Color.FromArgb(p, q, CByte(hsv.V * 255))
Case 4
retValue = Color.FromArgb(t, p, CByte(hsv.V * 255))
Case 5
retValue = Color.FromArgb(CByte(hsv.V * 255), p, q)
End Select
End If
Return retValue
End Function
///
Die Methode ist sehr schön anzuwenden wenn man bspw. ein Fadenkreuz oder
Text zeichen muss und dieses/ dieser auf jeden Fall sichtbar ist egal
welcher Hintergrund gegeben ist.
Ein Nachteil hat die ganze Geschichte aber. Die Funktionalitàt ist nicht
umkehrbar. :=( Vielleicht findet von Euch ja noch Eine(r) eine.
Gruß Scotty
 

Lesen sie die antworten

#1 Robert Schneider
08/10/2007 - 08:19 | Warnen spam
Hi Karsten,

habe zwar eigentlich noch nie mit dieser Sache direkt etwas zu tun gehabt,
kann mir trotzdem eine andere Lösung vorstellen, die auch eine Umkehrung
erlaubt.

Wenn eine Teilfarbe (Rot, Grün, Blau) einen gewissen Wert hat, dann wird für
die 'Negation' einfach ein gewisser Wert addiert. Für die Umkehrung dann
wieder subtrahiert. Z.B. 100. Ein Überlauf muss natürlich berücksichtigt
werden.

Aus
R 1
G"
BW

wird

RE [ wegen Überlauf: ((201+100) mod 256) = 45 ]
G2
B7

und zurück:

R 1 [ wegen vorherigen Überlauf: ((45-100+256) mod 256) = 45 ]
G"
BW

Bin mir nur nicht sicher, ob es dann IMMER zu einem gewünschten Kontrast
kommt. Naja, außerdem hoffe ich, dass ich keinen gedanklichen Fehler gemacht
haben. Irgendwann bin ich das schon einmal im Kopf durchgegangen und dachte
mir, so könnte es gehen.

Was meinst du?

Grüße aus Österreich,
Robert
e-mail: r_.s_chnei_der\wein_gart_ner.com (remove all '_' and replace '\'
with
'@')

Ähnliche fragen