Codage couleurs RGB <==> HSL

Partagez votre expérience de PureBasic avec les autres utilisateurs.
Avatar de l’utilisateur
TazNormand
Messages : 1297
Inscription : ven. 27/oct./2006 12:19
Localisation : Calvados (14)

Codage couleurs RGB <==> HSL

Message par TazNormand »

Salut,

comme cela faisait très très longtemps que je n'avais pas contribué concrètement au forum, voici un code que j'avais fait il y a quelques mois. :oops:

Il permet de faire une conversion RGB vers HSL et vice versa via 2 fonctions :
RGB2HSL(R.i,V.i,B.i) qui renvoie Hue, Sat et Light (Teinte, Saturation et Lumière)
HSL2RGB(H.f,S.f,L.f) qui renvoie Rouge, Vert et Bleu

J'ai inclus un petit code (pas propre désolé) où on peut jouer sur les valeurs HSL via le clavier

si jamais ça peut servir à quelqu'un ? Je voulais essayer de "bricoler" un effet plasma en jouant sur la Sat et la teinte, mais j'ai abandonné depuis.

C'est une adaptation du code trouvé ici : http://www.easyrgb.com/index.php?X=MATH&H=18#text18

Code : Tout sélectionner

; Procédure pour conversion RGB<->HSL
;
; ©.2011 TazNormand

; En TSL (HSL en anglais), la teinte est un angle de 0 à 360°
; La saturation une valeur de 0 à 100%, de même pour la luminosité 0 à 100%

; Variables
Global.f Hue,Sat,Light
Global.l Rouge,Vert,Bleu,Alph

; Déclarations
Declare RGB2HSL(ColR.i,ColG.i,ColB.i)
Declare HSL2RGB(VHue.f,VSat.f,VLit.f)
Declare.f Hue2RGB(Val1.f,Val2.f,Val_H.f)
Declare.f Mini2(val_1.f,val_2.f)
Declare.f Mini3(val_1.f,val_2.f,val_3.f)
Declare.f Maxi2(val_1.f,val_2.f)
Declare.f Maxi3(val_1.f,val_2.f,val_3.f)

; Procédures
Procedure RGB2HSL(ColR.i,ColG.i,ColB.i)
  var_R.f=(ColR/255)
  var_G.f=(ColG/255)
  var_B.f=(ColB/255)
  
  var_Min.f=Mini3(var_R,var_G,var_B)
  var_Max.f=Maxi3(var_R,var_G,var_B)
  del_Max.f=var_Max - var_Min
  
  Light=((var_Max + var_Min) / 2)*100
  
  If del_Max=0
    Hue=0
    Sat=0
  Else
    If Light<=0.5
      Sat=(del_Max / (var_Max + var_Min))*100
    Else
      Sat=(del_Max / (2 - (var_Max + var_Min)))*100
    EndIf
    
    del_R.f=(((var_Max - var_R) / 6) + (del_Max / 2)) / del_Max    
    del_G.f=(((var_Max - var_G) / 6) + (del_Max / 2)) / del_Max    
    del_B.f=(((var_Max - var_B) / 6) + (del_Max / 2)) / del_Max    
      
    If var_R=var_Max            
      Hue=del_B - del_G      
      Hue=((60 * ((var_g - var_b) / del_max)) + 360); % 360      
      ;Else      
    ElseIf var_G=var_Max    
      Hue=(1 / 3) + del_R - del_B      
      Hue=(60 * ((var_b - var_r) / del_Max)+120)      
    ElseIf var_B=var_Max      
      Hue=(2 / 3) + del_G - del_R
      Hue=360*Hue
    EndIf        
    ;EndIf  
      
    If Hue<0      
      Hue+360      
    EndIf    
    
    If Hue>360      
      Hue-360      
    EndIf  
  EndIf   
EndProcedure

Procedure HSL2RGB(VHue.f,VSat.f,VLit.f)
  vHue/360
  VSat/100
  VLit/100
  If VSat=0
    Rouge=VLit * 255
    Vert= VLit * 255
    Bleu= VLit * 255
  Else
    If VLit<0.5
      tmp_2.f=VLit * (1 + VSat)
    Else
      tmp_2.f=(VLit + VSat) - (VSat * VLit)
    EndIf
    
    tmp_1.f=(2 * VLit) - tmp_2
    
    Rouge=Int(255 * Hue2RGB(tmp_1,tmp_2,VHue + (1 / 3)))
    Vert =Int(255 * Hue2RGB(tmp_1,tmp_2,VHue))
    Bleu =Int(255 * Hue2RGB(tmp_1,tmp_2,VHue - (1 / 3)))
  EndIf  
EndProcedure

Procedure.f Hue2RGB(Val1.f,Val2.f,Val_H.f)
  If Val_H<0
    Val_H+1
  EndIf
  If Val_H>1
    Val_H-1
  EndIf
  If (6 * Val_H)<1
    tmp.f=(Val1 + (Val2 - Val1) * 6 * Val_H)
    ProcedureReturn tmp
  EndIf
  If (2 * Val_H)<1
    tmp.f=Val2
    ProcedureReturn tmp  
  EndIf
  If (3 * Val_H)<2
    tmp.f=(Val1 + (Val2 - Val1) * ((2 / 3) - Val_H) * 6)
    ProcedureReturn tmp  
  EndIf
  
  ProcedureReturn Val1  
EndProcedure

Procedure.f Mini3(val_1.f,val_2.f,val_3.f)
  tmp_1.f=Mini2(val_1,val_2)
  min_3.f=Mini2(tmp_1,val_3)
  
  ProcedureReturn min_3
EndProcedure

Procedure.f Maxi3(val_1.f,val_2.f,val_3.f)
  tmp_1.f=Maxi2(val_1,val_2)
  max_3.f=Maxi2(tmp_1,val_3)
  
  ProcedureReturn max_3
EndProcedure

; Minimum entre 2 valeurs
Procedure.f Mini2(val_1.f,val_2.f)
  If val_1<=val_2
    minimum2.f=val_1
  Else
    minimum2.f=val_2
  EndIf
  ProcedureReturn minimum2
EndProcedure

; Maximum entre 2 valeurs
Procedure.f Maxi2(val_1.f,val_2.f)
  If val_1<=val_2
    maximum2.f=val_2
  Else
    maximum2.f=val_1
  EndIf
  ProcedureReturn maximum2
EndProcedure

#ScrW = 640
#ScrH = 480
#ScrD = 32

If InitSprite() = 0 Or InitKeyboard() = 0 
  MessageRequester( "Erreur" , "Initialisations impossibles", 0)
  End
ElseIf OpenScreen( #ScrW , #ScrH , #ScrD , "HSL Plasma" ) = 0
  MessageRequester( "Erreur" , "Ouverture écran impossible" , 0 )
  End
EndIf
H.f=180
S.f=50
L.f=50
Repeat
  ExamineKeyboard()
  StartDrawing(ScreenOutput())    
      DrawText(0,00,"E pour Hue-,   R pour Hue+",RGB(255,255,255))
      DrawText(0,20,"D pour Sat-,   F pour Sat+",RGB(255,255,255))
      DrawText(0,40,"C pour Light-, V pour Light+",RGB(255,255,255))
      DrawText(0,60,"Escape pour sortir",RGB(255,0,0))
      
      DrawText(300,00,"Hue : "+Str(H)+"°    ",RGB(255,255,255))
      DrawText(300,20,"Sat : "+Str(S)+"%    ",RGB(255,255,255))
      DrawText(300,40,"Lit : "+Str(L)+"%    ",RGB(255,255,255))
      
      DrawText(400,00,"Rouge : "+Str(Rouge)+"    ",RGB(255,255,255))
      DrawText(400,20,"Vert  : "+Str(Vert)+"    ",RGB(255,255,255))
      DrawText(400,40,"Bleu  : "+Str(Bleu)+"    ",RGB(255,255,255))
      
      If KeyboardPushed(#PB_Key_E)
        H-1
        If H<0:H=359:EndIf
      EndIf
      If KeyboardPushed(#PB_Key_R)
        H+1
        If H>360:H=0:EndIf
      EndIf
      If KeyboardPushed(#PB_Key_D)
        S-1
        If S<0:S=0:EndIf
      EndIf
      If KeyboardPushed(#PB_Key_F)
        S+1
        If S>100:S=100:EndIf
      EndIf
      If KeyboardPushed(#PB_Key_C)
        L-1
        If L<0:L=0:EndIf
      EndIf
      If KeyboardPushed(#PB_Key_V)
        L+1
        If L>100:L=100:EndIf
      EndIf
      
      hsltransform=HSL2RGB(H,S,L)      
      Box(100,100,200,200,RGB(Rouge,Vert,Bleu))  
  StopDrawing()
  FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)
Image
Image
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: Codage couleurs RGB <==> HSL

Message par G-Rom »

Toujours pratique ce genre de code pour faire du traitement sur image , merci taz !

@+
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Codage couleurs RGB <==> HSL

Message par djes »

Oui, ça peut être utile, merci :)
kelebrindae
Messages : 579
Inscription : ven. 11/mai/2007 15:21

Re: Codage couleurs RGB <==> HSL

Message par kelebrindae »

Ah oui, c'est super pratique pour faire des dégradés; merci beaucoup!
(ce serait sympa que ce soit intégré nativement à PB, non ?)
Les idées sont le souvenir de choses qui ne se sont pas encore produites.
kelebrindae
Messages : 579
Inscription : ven. 11/mai/2007 15:21

Re: Codage couleurs RGB <==> HSL

Message par kelebrindae »

Pour mettre en évidence à quel point le code de Taz peut être utile, je l'ai ajouté à un ch'tit programme qui s'y prêtait bien.

(pour la petite histoire, j'ai trouvé ce code il y a quelques semaines sur les forums de DarkBasic et à l'époque, je l'avais adapté en PB pour comparer les vitesses d'exécution. Résultat: PB est beaucoup plus rapide, en 2D en tout cas... :roll: )

Code : Tout sélectionner

; Window size
#SCREENWIDTH = 800
#SCREENHEIGHT = 500
#HALFWIDTH = #SCREENWIDTH / 2
#HALFHEIGHT = #SCREENHEIGHT / 2
#PIXELSIZE = #SCREENWIDTH / 40

EnableExplicit

Define.f ang,ang2,x,y,z,rx,ry,rz,px,py,min,max,hue
Define.i i,j,brightness,sx,sy

Structure pixel_struct
  x.f
  y.f
  z.f
  
  RealHeight.f
EndStructure
Global NewList pixel.pixel_struct()

;********************************************************
;- --- Procedures ---
;********************************************************
Procedure.f Hue2RGB(Val1.f,Val2.f,Val_H.f) ; by TazNormand !
  Protected tmp.f
  
  If Val_H<0
    Val_H+1
  EndIf
  If Val_H>1
    Val_H-1
  EndIf
  If (6 * Val_H)<1
    tmp.f=(Val1 + (Val2 - Val1) * 6 * Val_H)
    ProcedureReturn tmp
  EndIf
  If (2 * Val_H)<1
    tmp.f=Val2
    ProcedureReturn tmp 
  EndIf
  If (3 * Val_H)<2
    tmp.f=(Val1 + (Val2 - Val1) * ((2 / 3) - Val_H) * 6)
    ProcedureReturn tmp 
  EndIf
 
  ProcedureReturn Val1 
EndProcedure

Procedure HSL2RGB(VHue.f,VSat.f,VLit.f) ; by TazNormand !
  Protected rouge.f, vert.f, bleu.f,tmp_1.f,tmp_2.f
  
  vHue/360
  VSat/100
  VLit/100
  If VSat=0
    Rouge=VLit * 255
    Vert= VLit * 255
    Bleu= VLit * 255
  Else
    If VLit<0.5
      tmp_2.f=VLit * (1 + VSat)
    Else
      tmp_2.f=(VLit + VSat) - (VSat * VLit)
    EndIf
   
    tmp_1.f=(2 * VLit) - tmp_2
   
    Rouge=Int(255 * Hue2RGB(tmp_1,tmp_2,VHue + (1 / 3)))
    Vert =Int(255 * Hue2RGB(tmp_1,tmp_2,VHue))
    Bleu =Int(255 * Hue2RGB(tmp_1,tmp_2,VHue - (1 / 3)))
  EndIf 
  
  ProcedureReturn RGB(rouge,vert,bleu)
EndProcedure


;********************************************************
;- --- Main program ---
;********************************************************

;- initialization
InitSprite()
InitSprite3D()
InitKeyboard()

;- Window
OpenWindow(0, 0, 0, #SCREENWIDTH, #SCREENHEIGHT, "pixel plane", #PB_Window_ScreenCentered|#PB_Window_SystemMenu|#PB_Window_MinimizeGadget)
OpenWindowedScreen(WindowID(0), 0, 0, #SCREENWIDTH,#SCREENHEIGHT, 0, 0, 0,#PB_Screen_WaitSynchronization)

; Main loop
Repeat
  While WindowEvent() : Wend

  ang2 + 1
  ang = Radian(ang2)
  
  ;- Compute pixels' position
  ClearList(pixel())
  For j=-16 To 16
    For i=-16 To 16
      
      x=i:z=j  
      
      ; Ondulation on the Y axis
      y = Sin(ang + ((Cos(ang)*#PI+#PI)/31.0)*x) * 5.0
      y + Cos(ang + ((Sin(ang*1.5)*#PI+#PI)/31.0)*z) * 5.0
      
      ; Rotation
      rx = x * Cos(ang) + z * Sin(ang)
      rz = x * -Sin(ang) + z * Cos(ang)
      
      ry = y * Cos(-#PI/8) - rz * Sin(-#PI/8)
      rz = y * Sin(-#PI/8) + rz * Cos(-#PI/8)
      
      px = rx / (rz + 35.0)
      py = ry / (rz + 35.0)
      
      ; Store coords
      AddElement(pixel())
      pixel()\x = px
      pixel()\y = py
      pixel()\z = rz
      pixel()\RealHeight = y

    Next i
  Next j

  
  ;- Drawing
  ; Sort pixels on Z axis (farthest pixels are drawn first)
  SortStructuredList(pixel(),#PB_Sort_Descending,OffsetOf(pixel_struct\z),#PB_Sort_Float)
  
  ; Find minimum and maximum Z values (depth)
  LastElement(pixel())
  min = pixel()\z
  FirstElement(pixel())
  max = pixel()\z
  
  ; Draw pixels
  ClearScreen(0)
  StartDrawing(ScreenOutput())
    ForEach pixel()
      ; Compute brightness according to current pixel's depth (farthest are darkest)
      brightness = 100 + ((-pixel()\z + min) * (100 / (max - min)))
      If brightness < 0
        brightness = 0
      ElseIf brightness > 100
        brightness = 100      
      EndIf
      
      ; Compute hue according to pixel height
      hue = (pixel()\RealHeight + 10) * 18
      If hue < 0
        hue = 0
      ElseIf hue > 360
        hue = 360      
      EndIf
           
      ; Compute pixel's position on screen
      sx = pixel()\x * #HALFWIDTH + #HALFWIDTH
      sy = -pixel()\y * #HALFHEIGHT + #HALFHEIGHT
      
      ; Draw the pixel
      Box(sx,sy,#PIXELSIZE,#PIXELSIZE,HSL2RGB(hue,100,brightness))
  
    Next pixel()
  StopDrawing()
  
  FlipBuffers()
    
  ExamineKeyboard()
Until KeyboardPushed(#PB_Key_Escape)

End
Les idées sont le souvenir de choses qui ne se sont pas encore produites.
Avatar de l’utilisateur
venom
Messages : 3137
Inscription : jeu. 29/juil./2004 16:33
Localisation : Klyntar
Contact :

Re: Codage couleurs RGB <==> HSL

Message par venom »

c'est chouette tout ça :D






@++
Windows 10 x64, PureBasic 5.73 x86 & x64
GPU : radeon HD6370M, CPU : p6200 2.13Ghz
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Re: Codage couleurs RGB <==> HSL

Message par Kwai chang caine »

Splendide 8O
Merci :wink:
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
Avatar de l’utilisateur
TazNormand
Messages : 1297
Inscription : ven. 27/oct./2006 12:19
Localisation : Calvados (14)

Re: Codage couleurs RGB <==> HSL

Message par TazNormand »

@Kelebrindae : Merci pour la démo, un superbe plasma, c'était ce que je voulais faire avec cette fonction.

J'ai encore beaucoup à apprendre en PB :cry:
Image
Image
Fred
Site Admin
Messages : 2808
Inscription : mer. 21/janv./2004 11:03

Re: Codage couleurs RGB <==> HSL

Message par Fred »

Tres sympa
Répondre