Page 1 sur 1

Codage couleurs RGB <==> HSL

Publié : lun. 21/mars/2011 22:26
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)

Re: Codage couleurs RGB <==> HSL

Publié : lun. 21/mars/2011 23:36
par G-Rom
Toujours pratique ce genre de code pour faire du traitement sur image , merci taz !

@+

Re: Codage couleurs RGB <==> HSL

Publié : mar. 22/mars/2011 8:51
par djes
Oui, ça peut être utile, merci :)

Re: Codage couleurs RGB <==> HSL

Publié : mar. 22/mars/2011 9:43
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 ?)

Re: Codage couleurs RGB <==> HSL

Publié : mar. 22/mars/2011 16:28
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

Re: Codage couleurs RGB <==> HSL

Publié : mar. 22/mars/2011 17:52
par venom
c'est chouette tout ça :D






@++

Re: Codage couleurs RGB <==> HSL

Publié : mar. 22/mars/2011 18:29
par Kwai chang caine
Splendide 8O
Merci :wink:

Re: Codage couleurs RGB <==> HSL

Publié : mar. 22/mars/2011 20:50
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:

Re: Codage couleurs RGB <==> HSL

Publié : mer. 23/mars/2011 17:49
par Fred
Tres sympa