[erledigt] RGB -> HSV / HSV -> RGB Konvertierungfehler

Übersicht BlitzMax, BlitzMax NG Allgemein

Neue Antwort erstellen

d-bug

Betreff: [erledigt] RGB -> HSV / HSV -> RGB Konvertierungfehler

BeitragMi, Nov 01, 2006 19:13
Antworten mit Zitat
Benutzer-Profile anzeigen
Achtung, dieser Thread enthält langen Quelltext. Wessen Augen das nicht vertragen können, der möchte doch bitte den Thread wieder schließen. Wink

Wie ihr sicherlich aus dem Threadtitel ersehen konntet, geht es bei dem folgenden Code um die Konvertierung von Farbwerten. Natürlich ist da
noch mehr drin zu sehen, aber das alles in eine neue Dummy-Routine zu packen, dazu hatte ich einfach keine Lust. *schäm*

So, folgendes ist mein Problem:
Irgendwo ist bei der Konvertierung von HSV nach RGB u/o umgekehrt der Wurm drin. In dem Test, den ich starte, versuche ich die Farbe $FFFF00FF (also Pink) von RGB nach HSV zu konvertieren und das Ergebnis wieder zurück nach RGB.

BlitzMax-Konsole hat Folgendes geschrieben:
Probe:
A:1.00000000
R:255.000000
G:0.000000000
B:255.000000
Hex:$FFFF00FF
H:300.000000
S:1.00000000
V:1.00000000

Gegenprobe:
A:1.00000000
R:0.000000000
G:0.000000000
B:255.000000
Hex:$FF0000FF
H:240.000000
S:1.00000000
V:1.00000000

Wie man sieht wurde aus Rot 255 bei der Gegenprobe Rot 0, dementsprechend wurde aus Hue 300 dann Hue 240. Leider sehe ich im Moment nurnoch Wald, anstatt Bäume. Will heißen, ich finde den Fehler einfach nicht.

Ich wäre euch sehr verbunden, wenn jemand mal ein Auge darauf werfen würde.

Code: [AUSKLAPPEN]

Local blub:CUIColor = CUIColor.FromARGB (1.0,255,0,255)
Local blub2:CUIColor = CUIColor.FromHSV (blub.hue,blub.saturation,blub.value)

Print "~nProbe:"
Print "A:"+blub.alpha
Print "R:"+blub.red
Print "G:"+blub.green
Print "B:"+blub.blue
Print "Hex:$"+Hex(blub.Hexadecimal)
Print "H:"+blub.hue
Print "S:"+blub.saturation
Print "V:"+blub.value
Print "~nGegenprobe:"
Print "A:"+blub2.alpha
Print "R:"+blub2.red
Print "G:"+blub2.green
Print "B:"+blub2.blue
Print "Hex:$"+Hex(blub2.Hexadecimal)
Print "H:"+blub2.hue
Print "S:"+blub2.saturation
Print "V:"+blub2.value


Type CUIColor

   Const ALPHAVALUE:Int =   %1000
   Const REDVALUE:Int =      %0100
   Const GREENVALUE:Int =   %0010
   Const BLUEVALUE:Int =   %0001

   Global Cache:CUIColor[]
   Global CustomCount:Int = 0

   Field Handle:String
   Field Alpha:Float
   Field Red:Float
   Field Green:Float
   Field Blue:Float
   Field Hue:Float
   Field Saturation:Float
   Field Value:Float
   Field Hexadecimal:Int


   '-- Aktuelle Zeichenfarbe setzen -------------------------------------
   Method Set (   mixwith:CUIColor = Null,..
            mode:Int = CUIColor.ALPHAVALUE|CUIColor.REDVALUE|CUIColor.GREENVALUE|CUIColor.BLUEVALUE)

      Local alpha:Float   = self.Alpha
      Local red:Int      = self.Red
      Local green:Int   = self.Green
      Local blue:Int   = self.Blue
      If mixwith <> Null
         If (mode & CUIColor.ALPHAVALUE)    Then alpha = Interpolate(self.Alpha,1,mixwith.Alpha)
         If (mode & CUIColor.REDVALUE)       Then red = Interpolate(self.Red,255,mixwith.Red)
         If (mode & CUIColor.GREENVALUE)    Then green = Interpolate(self.Green,255,mixwith.Green)
         If (mode & CUIColor.BLUEVALUE)       Then blue = Interpolate(self.Blue,255,mixwith.Blue)
      EndIf
      .SetAlpha(alpha)
      .SetColor(red,green,blue)
   End Method



   '-- Farbe nach ARGB Werten festlegen -------------------------------
   Method DefineARGB (   alpha:Float=1.0,..
                  red:Int=255,..
                  green:Int=255,..
                  blue:Int=255)
      self.DefineAlpha (alpha)
      self.DefineRed (red)
      self.DefineGreen (green)
      self.DefineBlue (blue)
      ToHSV(Self)
      ToHex(Self)
   End Method


   '-- Transparenz festlegen -------------------------------------------
   Method DefineAlpha (alpha:Float=1.0)
      If alpha < 0.0 Then alpha = 0.0
      If alpha > 1.0 Then alpha = 1.0
      self.Alpha = alpha
   End Method


   '-- Roten Farbanteil festlegen ---------------------------------------
   Method DefineRed (value:Int=255)
      If value < 0 Then value = 0
      If value > 255 Then value = 255
      self.Red = value
      ToHSV(Self)
      ToHex(Self)
   End Method


   '-- Grünen Farbanteil festlegen --------------------------------------
   Method DefineGreen (value:Int=255)
      If value < 0 Then value = 0
      If value > 255 Then value = 255
      self.Green = value
      ToHSV(Self)
      ToHex(Self)
   End Method


   '-- Blauen Farbanteil festlegen --------------------------------------
   Method DefineBlue (value:Int=255)
      If value < 0 Then value = 0
      If value > 255 Then value = 255
      self.Blue = value
      ToHSV(Self)
      ToHex(Self)
   End Method


   '-- Hex nach Farbe konvertieren ------------------------------------
   Function FromHex (value:Int)
'TODO:FromHex
   End Function


   '-- Farbe nach HSV konvertieren ------------------------------------
   Function FromHSV:CUIColor (   hue:Float,..
                        saturation:Float,..
                        value:Float)
      Local red:Float, green:Float, blue:Float
      If hue => 360.0 Or hue < 0.0 Then hue = 0.0
      If saturation = 0 Then
         red = v
         green = v
         blue = v
      Else
         hue = hue / 60.0
         Local i:Int   = Floor(hue)
         Local f:Float = hue - i
         Local p:Float = value * (1.0 - saturation)
         Local q:Float = value * (1.0 - saturation * f)
         Local t:Float = value * (1.0 - saturation * (1.0 - f))
         Select i
            Case 0 ; red = v ;   green = t ; blue = p
            Case 1 ; red = q ; green = v ; blue = p
            Case 2 ; red = p ; green = v ; blue = t
            Case 3 ; red = p ; green = q ; blue = v
            Case 4 ; red = t ;    green = p ; blue = v
            Default ; red = v ; green = p ; blue = q
         End Select      
      EndIf
      Return FromARGB(1.0,Interpolate(red,1,255),Interpolate(green,1,255),Interpolate(blue,1,255))
   End Function


   '-- Farb-Klasse aus aktueller Farbe erstellen -------------------------
   Function FromSystem:CUIColor ()
      Local red:Int,green:Int,blue:Int
      .GetColor (red,green,blue)
      Return FromARGB (.GetAlpha(),red,green,blue)
   End Function


   '-- Farb-Klasse aus ARGB-Werten erstellen --------------------------
   Function FromARGB:CUIColor (   alpha:Float = 1.0,..
                        red:Int = 255,..
                        green:Int = 255,..
                        blue:Int = 255)
      Local color:CUIColor = CUIColor.Create()
      color.DefineARGB(alpha,red,green,blue)
      Return color
   End Function


   '-- Farb-Klasse erstellen ---------------------------------------------
   Function Create:CUIColor (handle:String="")

         Function Find:CUIColor (handle:String)
            For color:CUIColor = EachIn CUIColor.Cache
               If color.Handle = handle Return color
            Next
            Return Null
         End Function

      If handle = ""
         CUIColor.CustomCount:+1
         handle =    "custom"+CUIColor.CustomCount
      EndIf
      Local color:CUIColor = Find(handle)
      If color = Null
         color = New CUIColor
         color.Handle = handle
         CUIColor.Cache = CUIColor.Cache[..CUIColor.Cache.length+1]
         CUIColor.Cache[CUIColor.Cache.length-1] = color
      EndIf
      Return color
   End Function

End Type

Private
   Function Interpolate:Float (value:Float,..
                     valmax:Float,..
                     retmax:Float)
      Return (value * (retmax / valmax))
   End Function

   Function ToHSV (color:CUIColor)
      Local red:Float = Min(1.0,Max(0.0,Interpolate(color.Red,255,1.0)))
      Local green:Float = Min(1.0,Max(0.0,Interpolate(color.Green,255,1.0)))
      Local blue:Float = Min(1.0,Max(0.0,Interpolate(color.Blue,255,1.0)))
      Local ValueMin:Float = Min(Min(red,green),blue)
      Local ValueMax:Float = Max(Max(red,green),blue)
      Local diff:Float = ValueMax - ValueMin
      color.Value = ValueMax
      If ValueMax = 0.0 Then
         color.Saturation = 0.0
         color.Hue = 0.0
      Else
         color.Saturation = diff / ValueMax
         If red = ValueMax
            color.Hue = (green - blue) / diff
         ElseIf green = ValueMax
            color.Hue = 2.0 + (blue - red) / diff
         Else
            color.Hue = 4.0 + (red - green) / diff
         EndIf
         color.Hue = color.Hue * 60.0
         If color.Hue < 0 Then color.Hue = color.Hue + 360.0
      EndIf
      If color.Hue<  0.0 Then color.Hue = 0.0
      If color.Hue > 360.0 Then color.Hue = 0.0
   End Function

   Function ToHex (color:CUIColor)
      color.Hexadecimal = (Int(Interpolate(color.Alpha,1,255)) Shl 24) | (Int(color.Red) Shl 16) | (Int(color.Green) Shl 8) | Int(color.Blue)
   End Function

Public


Wie immer, bedanke ich mich für eure Aufmerksamkeit.

cheers
  • Zuletzt bearbeitet von d-bug am Mi, Nov 01, 2006 21:24, insgesamt einmal bearbeitet
 

blitzatius

BeitragMi, Nov 01, 2006 21:09
Antworten mit Zitat
Benutzer-Profile anzeigen
Hi,
Bin jetzt glaub eine Stunde daran gesessen. Wollte auch unbedingt wissen, wo der Fehler liegt Twisted Evil .

Diese Funktion einfach kopieren und deine überschreiben...
Code: [AUSKLAPPEN]
 Function FromHSV:CUIColor (   hue:Float,..
                        saturation:Float,..
                        v:Float)
      Local red:Float, green:Float, blue:Float
      If hue => 360.0 Or hue < 0.0 Then hue = 0.0
      If saturation = 0 Then
         red = v
         green = v
         blue = v
      Else
         hue = hue / 60.0
         Local i:Int   = Floor(hue)
         Local f:Float = hue - i
         Local p:Float = v * (1.0 - saturation)
         Local q:Float = v * (1.0 - saturation * f)
         Local t:Float = v * (1.0 - saturation * (1.0 - f))
         Select i
            Case 0 ; red = v ;   green = t ; blue = p
            Case 1 ; red = q ; green = v ; blue = p
            Case 2 ; red = p ; green = v ; blue = t
            Case 3 ; red = p ; green = q ; blue = v
            Case 4 ; red = t ;    green = p ; blue = v
            Default ; red = v ; green = p ; blue = q
         End Select     
      EndIf
      Return FromARGB(1.0,Interpolate(red,1,255),Interpolate(green,1,255),Interpolate(blue,1,255))
   End Function


Der Fehler: Du hast in der Funktion manchmal v und manchmal value benutzt Smile

d-bug

BeitragMi, Nov 01, 2006 21:24
Antworten mit Zitat
Benutzer-Profile anzeigen
OMG, das tut echt weh... Rolling Eyes
Hatte mir schon gedacht, dass es sich um einen Flüchtigkeitsfehler handeln
würde, aber sowas doofes ist mir ja schon lange nicht mehr passiert.

Danke für deine Mühe, blitzatius.

cheers

Artemis

BeitragDo, Nov 02, 2006 20:52
Antworten mit Zitat
Benutzer-Profile anzeigen
Hmm, es gibt auf dem offiziellen Modserver auch das Modul birdie.color, dass die Konvertierungen von RGB, HSV und CMY beinhaltet.

d-bug

BeitragDo, Nov 02, 2006 21:42
Antworten mit Zitat
Benutzer-Profile anzeigen
Ja, aber birdies Module sind nicht unbedingt mein Fall. Mal davon abgesehen,
dass auch er Saturation und Value nicht in % ausgibt. Was der Code da oben
auch nicht machte, es aber nun macht. Weiterhin brauche ich ein paar güldene
Zusatzfunktionen. Ich könnte dir jetzt noch zig Gründe nennen. Smile

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group