HSB - Farbsystemumrechnung & Bild Färben

Übersicht BlitzBasic Codearchiv

Neue Antwort erstellen

Holzchopf

Meisterpacker

Betreff: HSB - Farbsystemumrechnung & Bild Färben

BeitragDo, Mai 28, 2009 19:34
Antworten mit Zitat
Benutzer-Profile anzeigen
(Gammelt seit Jahren auf meiner Festplatte rum - aber ich dachte, ich hätte das schon mal ins Codearchiv gestellt)

Einige kennen ja vielleicht das Farbsystem, in welchem eine Farbe über Farbton (Hue), Sättigung (Saturation) und Helligkeit (Brightness) definiert wird... Dieses Farbsystem hat doch tatsächlich den einen oder anderen Vorteil und die Umrechnung von RGB <-> HSB ist eigentlich ganz simpel.

Zum Beispiel kann man Bilder viel einfacher umfärben, wenn man die Pixel mit den HSB-Werten betrachtet (dann kann man unabhängig der Helligkeit und Sättigung rote Pixel lila machen usw)

Dieser Code enthält die Funktionen für die Umrechnung RGB <-> HSB
Code: [AUSKLAPPEN]
;*****************************
;
;   HSB Farbsystem
;
;-----------------------------
; Autor:      Holzchopf
; Erstellt:      07.11.2005
; Bearbeitet:   28.05.2009
;=============================
;
;   Berechnet aus RGB-Farben HSB-Farben und umgekehrt, die berechneten Resultate
;   werden in den Variablen HSB_xxxx gespeichert
;
;*****************************

; Farbton, Sättigung, Helligkeit
Global HSB_Hue, HSB_Saturation, HSB_Brightness
; Rotanteil, Grünanteil, Blauanteil
Global HSB_Red, HSB_Green, HSB_Blue

;========================
; RGB -> HSB
; Parameter:
;   Rotanteil   0 -255
;   Grünanteil   0 -255
;   Blauanteil   0 -255
; Resultate werden in den globalen Variablen
;   HSB_Hue, HSB_Saturation und HSB_Brightness
;   gespeichert
Function HSB_ConvertToHSB( HSB_R, HSB_G, HSB_B )
   ; Höchstwert
   Local HSB_Max = HSB_R
   If HSB_G > HSB_Max Then HSB_Max = HSB_G
   If HSB_B > HSB_Max Then HSB_Max = HSB_B
   
   ; Mindesstwert
   Local HSB_Min = HSB_R
   If HSB_G < HSB_Min Then HSB_Min = HSB_G
   If HSB_B < HSB_Min Then HSB_Min = HSB_B
   
   If HSB_Max = HSB_Min   ; Spezialfall "grau"
      HSB_Hue = 0                     ; Farbton
      HSB_Saturation = 0               ; Sättigung
      HSB_Brightness = HSB_Max /2.55      ; Helligkeit
   Else
      ; Farbton
      If HSB_R = HSB_Max   ; Rot ist am stärksten
         HSB_Hue = Float( 0 +( HSB_G -HSB_B ) /Float( HSB_Max -HSB_Min ) ) *60.0
      ElseIf HSB_G = HSB_Max   ; Grün ist am stärksten
         HSB_Hue = Float( 2 +( HSB_B -HSB_R ) /Float( HSB_Max -HSB_Min ) ) *60.0
      Else   ; Blau ist am stärksten
         HSB_Hue = Float( 4 +( HSB_R -HSB_G ) /Float( HSB_Max -HSB_Min ) ) *60.0
      EndIf
      
      ; Negativer Wert verhindern
      HSB_Hue = ( HSB_Hue +360 ) Mod 360
      
      ; Sättigung
      HSB_Saturation = Float( HSB_Max - HSB_Min ) / Float( HSB_Max ) * 100
      
      ; Helligkeit
      HSB_Brightness = HSB_Max /2.55
   EndIf
End Function

;========================
; HSB -> RGB
; Parameter:
;   Farbton      0 -359
;   Sättigung   0 -100
;   Helligkeit   0 -100
; Resultate werden in den globalen Variablen
;   HSB_Red, HSB_Green und HSB_Blue
;   gespeichert
Function HSB_ConvertToRGB( HSB_H, HSB_S, HSB_B )
   If HSB_S = 0   ; Spezialfall "schwarz"
      HSB_Red = HSB_B *2.55
      HSB_Green = HSB_B *2.55
      HSB_Blue = HSB_B *2.55
   ElseIf HSB_B = 0   ; Spezialfall 2 "grau"
      HSB_Red = 0
      HSB_Green = 0
      HSB_Blue = 0
   Else
      ; 360° für Farbton verhindern
      HSB_H = HSB_H Mod 360
      
      ; Farbraumindex
      Local HSB_Hi = Floor( HSB_H /60.0 )
      
      ; temporäre Farbwerte, linear interpoliert
      Local HSB_f# = Float( HSB_H /60.0 ) -HSB_Hi
      Local HSB_m = HSB_B * ( 100 -HSB_S ) /100.0
      Local HSB_n = HSB_B * ( 100 -( HSB_S *HSB_f ) ) /100.0
      Local HSB_o = HSB_B * ( 100 -( HSB_S *( 1 -HSB_f ) ) ) /100.0
      
      ; Werte von 0-100 zu 0-255
      HSB_B = HSB_B *2.55
      HSB_m = HSB_m *2.55
      HSB_n = HSB_n *2.55
      HSB_o = HSB_o *2.55
      
      ; Farbwerte
      If HSB_Hi = 0
         HSB_Red = HSB_B
         HSB_Green = HSB_o
         HSB_Blue = HSB_m
      ElseIf HSB_Hi = 1
         HSB_Red = HSB_n
         HSB_Green = HSB_B
         HSB_Blue = HSB_m
      ElseIf HSB_Hi = 2
         HSB_Red = HSB_m
         HSB_Green = HSB_B
         HSB_Blue = HSB_o
      ElseIf HSB_Hi = 3
         HSB_Red = HSB_m
         HSB_Green = HSB_n
         HSB_Blue = HSB_B
      ElseIf HSB_Hi = 4
         HSB_Red = HSB_o
         HSB_Green = HSB_m
         HSB_Blue = HSB_B
      ElseIf HSB_Hi = 5
         HSB_Red = HSB_B
         HSB_Green = HSB_m
         HSB_Blue = HSB_n
      EndIf
   EndIf
End Function

Ich empfehle, HSB Include.bb aus dem Archiv runterzuladen und als "HSB Include.bb" zu speichern.

Diese Funktionen besitzt die Macht, Farbtöne zu ändern
Code: [AUSKLAPPEN]
;*****************************
;
;   Colorize
;
;-----------------------------
; Autor:      Holzchopf
; Erstellt:      07.11.2005
; Bearbeitet:   28.05.2009
;=============================
;
;   Ändert bestimmte Farbtöne eines Bildes.
;
;-----------------------------
; Benötigt:
;   HSB Include.bb
;
;*****************************

;========================
; Colorize
; Parameter:
;   Eingangsbild
;   Ausgabebild
;   Neue Farbe,   rot      0 -255
;            grün   0 -255
;            blau   0 -255
;   Zu ändernder Farbton   0 -359
;   Farbtonbereich \ -toleranz
Function Colorize( Col_img, Col_imgOut, Col_r, Col_g, Col_b, Col_hueS, Col_Tol )

   Local Col_img_B = ImageBuffer( Col_img )
   Local Col_imgOut_B = ImageBuffer( Col_imgOut )
   LockBuffer Col_img_B
   LockBuffer Col_imgOut_B

   Local Col_w = ImageWidth( Col_img ) -1
   Local Col_h = ImageHeight( Col_img ) -1   
   
   HSB_ConvertToHSB Col_r, Col_g, Col_b
   Local Col_hueIn = HSB_Hue
   Local Col_satIn = HSB_Saturation
   Local Col_briIn = HSB_Brightness
   
   Local Col_x, Col_y
   For Col_y = 0 To Col_h
      For Col_x = 0 To Col_w
      
         Local Col_rgb = ReadPixelFast( Col_x, Col_y, Col_img_B )
         
         Local Col_rot = ( Col_rgb And $FF0000 ) Shr 16
         Local Col_gruen = ( Col_rgb And $FF00 ) Shr 8
         Local Col_blau = ( Col_rgb And $FF )
         
         HSB_ConvertToHSB Col_rot, Col_gruen, Col_blau
         
         Local Col_Diff = Abs( HSB_Hue - Col_hueS )
         If Col_Diff > 180 Then Col_Diff = 360 -Col_Diff
         
         If Col_Diff <= Col_Tol And HSB_Saturation > 0 Then
            Local Col_f# = Float( Col_Diff ) /Float( Col_Tol )
            Local Col_nf# = 1 -Col_f
            
            Local Col_sat = Col_satIn /100.0 *HSB_Saturation
            Local Col_bri = Col_briIn /100.0 *HSB_Brightness
            
            If Col_bri > 100 Then Col_bri = 100
            If Col_sat > 100 Then Col_sat = 100
            
            HSB_ConvertToRGB Col_hueIn, Col_sat, Col_bri
            
            Col_rgb = ( HSB_Red * Col_nf + Col_rot * Col_f ) Shl 16 Or ( HSB_Green * Col_nf + Col_gruen * Col_f ) Shl 8 Or ( HSB_Blue * Col_nf + Col_blau * Col_f )
            
            WritePixelFast Col_x, Col_y, Col_rgb, Col_imgOut_B
         EndIf
      Next
   Next
   
   UnlockBuffer Col_img_B
   UnlockBuffer Col_imgOut_B

End Function

Ich empfehle, Colorize Include.bb aus dem Archiv runterzuladen und als "Colorize Include.bb" zu speichern.

Und dieser Code demonstriert das ganze
Code: [AUSKLAPPEN]
;*****************************
;
;   Anwendungsbeispiel zu Colorize
;
;-----------------------------
; Benötigt:
;   HSB Include.bb
;   Colorize Include.bb
;
;*****************************

Graphics 320, 240, 0, 2
SetBuffer BackBuffer()
Global Timer = CreateTimer(60)

Include "H:\BlitzBasic\Includes\HSB Farbsystem\HSB Include.bb"
Include "Colorize Include.bb"


Local Figur = LoadImage( "figur.png" )
MaskImage Figur, 255, 0, 255

Local Figur2 = CopyImage( Figur )

; Farbton 0 (Rot) zu '255, 204, 0' umfärben
Colorize Figur, Figur2, 255, 204, 0, 0, 1
; Farbton 120 +/-60 (Grün) zu '128, 255, 255' umfärben
Colorize Figur, Figur2, 128, 255, 255, 120, 60
; Farbton 240 +/-10 (Blau) zu '255, 0, 0' umfärben
Colorize Figur, Figur2, 255, 0, 0, 240, 10

ClsColor 0,64,64
Cls

DrawImage Figur, 0,0
DrawImage Figur2, 100,0

Flip

WaitKey()
End

Voraussetzung ist natürlich, dass man HSB Include.bb, Colorize Include.bb und figur.png bestitzt.

Viel Spass damit! Die Funktionen können bestimmt für einige von euch von Nutzen sein =)

mfG

Edit:
Kleines Beispiel, was mit Colorize möglich ist:
user posted image
(der rote Helm wurde orange, das grüne hemd türkis und die blaue Hose rot)
Erledige alles Schritt um Schritt - erledige alles. - Holzchopf
CC BYBinaryBorn - Yogurt ♫ (31.10.2018)
Im Kopf da knackt's und knistert's sturm - 's ist kein Gedanke, nur ein Wurm

Chrise

Betreff: Re: HSB - Farbsystemumrechnung & Bild Färben

BeitragFr, Mai 29, 2009 13:43
Antworten mit Zitat
Benutzer-Profile anzeigen
Sehr genial!
Eine Frage aber trotzdem:
Ab wann wird die Farbe Rot als Rot angesehn? Es kann ja auch ein "Rot" sein, dass nen ganz kleinen Stich ins Orange übergeht.
Llama 1 Llama 2 Llama 3
Vielen Dank an Pummelie, der mir auf seinem Server einen Platz für LlamaNet bietet.

Holzchopf

Meisterpacker

BeitragFr, Mai 29, 2009 14:57
Antworten mit Zitat
Benutzer-Profile anzeigen
Das kann man mit der Toleranz (letzter Parameter) einstellen. Diese Farbtöne, die in der Toleranz liegen, werden linear überblendet (dh: je näher am eigentlichen Wert, umso mehr ists die neue Farbe).

user posted image
Zu sehen ist ein Farbverlauf über alle Farbtöne (0° - 359°).
Orange wurde gelb (Toleranz 5°), Gelb (60° ±10°) wurde Blau und Grün (120° ±30°) wurde Rot. Die drei Striche rechts demonstrieren, was passiert, wenn man (bei Türkis) eine Farbe nimmt, die nicht 100% Helligkeit aufweist, oder (bei Blau) ganz schwarz ist Arrow führt dazu, dass sie im weissen Bereich ausschweifen, denn 1. Weiss hat keine Farbe mehr und somit eigentlich auch kein Farbton und 2. bleibt echtes Schwarz schwarz, auch wenn man es mit Sonnenlicht bestrahlt (100% Helligkeit).
Nimmt man Weiss (auch wenn unbunt) passiert das nicht.
Dieses Verhalten kommt von der Funktion, die den Wert für den Farbton rücksichtslos überschreibt, aber Sättigung und Helligkeit vom Ursprungspixel mit den Werten der neuen Farbe multipliziert.

Beispiel:
Neue Farbe: 60°, 50%, 50% (Farbton, Sättigung, Helligkeit, blasses "Gelb")
Alte Farbe 1: 0°, 0%, 100% (reines Weiss)
Arrow Wird zu: 60° (überschrieben), 0% (50% von 0%), 50% (50% von 100%) (also kein reines Weiss mehr, sondern Grau, weil Helligkeit fehlt)
Alte Farbe 2: 0°, 100%, 100% (Knallrot)
Arrow Wird zu: 60° (überschrieben), 50% (50% von 100%), 50% (50% von 100%) (also die Ursprungsfarbe)
Alte Farbe 3: 0°, 100%, 0% (Schwarz)
Arrow Wird zu: 60° (überschrieben), 50% (50% von 100%), 0% (50% von 0%) (bleibt also Schwarz)

Dieses Verhalten liesse sich ändern, zB könnte man Helligkeit und Sättigung der Grundfarbe beibehalten und nur den Farbton verschieben, dann stünden dem Spieler (wenn dieser die neue Farbe bestimmen kann) blasse und dunkle Farben sozusagen nicht zur Verfügung, da jede Farbe auf die Buntheit und Leuchtkraft der Grundfarbe gesetzt würde.

mfG
Erledige alles Schritt um Schritt - erledige alles. - Holzchopf
CC BYBinaryBorn - Yogurt ♫ (31.10.2018)
Im Kopf da knackt's und knistert's sturm - 's ist kein Gedanke, nur ein Wurm

Chrise

BeitragFr, Mai 29, 2009 19:13
Antworten mit Zitat
Benutzer-Profile anzeigen
hui, sehr ausführliche Beispiele, scheinst an alles gedacht zu haben. Sehr gute Funktionen, werd ich demnächst vll mal beim Bildbearbeiten verwenden können.
Llama 1 Llama 2 Llama 3
Vielen Dank an Pummelie, der mir auf seinem Server einen Platz für LlamaNet bietet.

Neue Antwort erstellen


Übersicht BlitzBasic Codearchiv

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group