Page 1 sur 1

[ok] RGB et color selector

Publié : mar. 30/juin/2015 18:57
par blendman
salut

J'ai trouvé un code de LSI que j'ai adapté pour mon soft 2D (pour avoir un sélecteur de couleur).

Mais j'aimerai avoir l'actualisation de la couleur en fonction de la teinte de la couleur RGB choisi dans le requester().
Pour le moment, j'actualise mon sélecteur avec la couleur obtenue et non la teinte ^^.
Mais je ne sais pas comment faire pour avoir la teinte, puis actualiser sur le sélecteur de couleur.

Voici le code :

Code : Tout sélectionner

Enumeration ; gadget
  #G_ColorSelector
  #G_ColorArcEnCielSelect
  #btn_Color
EndEnumeration

Enumeration ; image
  #IMAGE_ColorSelector
EndEnumeration


Procedure SetColorSelector(color,x=0,y=0)
  
  Shared cursorX,cursorY
  
  R = Red(color)
  G = Green(color)
  B = Blue(color)
    
    If StartDrawing(ImageOutput(#IMAGE_ColorSelector))
      Box(0,0,256,256,RGBA(255,255,255,255))    
      DrawingMode(#PB_2DDrawing_AlphaBlend)
      For i = 0 To 255
        For j = 0 To 255
          Plot(i, j, RGBA($FF, $FF, $FF, i))
          Plot(i, j, RGBA(0, 0, 0, j))
        Next
      Next      
      For i = 0 To 255
        For j = 0 To 255		    
          Plot(i, j, RGBA(R, G, B, i))
          Plot(i, j, RGBA(0, 0, 0, j))
        Next
      Next
      StopDrawing()
    EndIf
  
  If StartDrawing(CanvasOutput(#G_ColorSelector))
    Box(0,0,256,256,RGB(255,255,255))    
    DrawingMode(#PB_2DDrawing_AlphaBlend)
    DrawImage(ImageID(#IMAGE_ColorSelector),0,0,GadgetWidth(#G_ColorSelector),GadgetHeight(#G_ColorSelector))
    If mode =1
      DrawingMode(#PB_2DDrawing_Outlined)
      Circle(x,y,8,#White)
      Circle(x,y,9,#Black)
      cursorX = x
      cursorY = y
    Else 
      DrawingMode(#PB_2DDrawing_Outlined)
      Circle(cursorX,cursorY,8,#White)
      Circle(cursorX,cursorY,9,#Black)
    EndIf    
    StopDrawing()
    
  EndIf 
    
EndProcedure

OpenWindow(0, 0, 0, 600,400, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

CreateImage(#IMAGE_ColorSelector,256,256)
CanvasGadget(#G_ColorSelector,10,10,256,256)
SetColorSelector(RGB(241,128,56))

ButtonGadget(#btn_Color, 300,10,100,50,"Change color")

Repeat
  Event = WaitWindowEvent()
  
  If event = #PB_Event_Gadget
    
    If EventGadget() = #btn_Color
      Color = ColorRequester(color)
      SetColorSelector(color)
    EndIf
    
  EndIf
  
Until Event = #PB_Event_CloseWindow
EDIT : ok, voir la solution au message9

Re: RGB et color selector

Publié : mer. 01/juil./2015 11:25
par blendman
Pour la souris, en fait, j'utilise le canvas et les eventype() du canvas ;)

tu peux aussi utiliser mon Gadget palette
oui, d'ailleurs, je pense que je vais m'en servir ;).
J'aimerai aussi un sélecteur de couleur en triangle (comme dans painter), comme ça je pourrais donner le choix aux utilisateurs du type de sélecteur qu'ils préfèrent : comme le tien, carré (comme blender, gimp, photoshop...), en triangle (comme painter), etc...
Mais ça ne résout pas mon soucis :)

J'ai besoin de connaitre la couleur lorsque je ne change que l'intensité de lumière par exemple.
Parce que j'ai un outil pipette, qui me permet de prendre la couleur sur un dessin et je dois pouvoir changer mon sélecteur de couleur en fonction de la couleur choisie (mais sans prendre en compte l'intensité, ni la saturation d'ailleurs ^^).

Donc Si j'ai saisi :
- H = hue, va de 0 à 240
- S = saturation, va de 0 à 240
- l = luminence (ou lumière ), va de 0 à 240

ou
- H = hue, va de 0 à 360°
- S = saturation, va de 0 à 100%
- B = brightness, va de 0 à 100%

Si j'ai rgb(120,60,189), je dois garder s et B à 100%, il me reste à trouver H ^^. Mais là, je sèche...

Re: RGB et color selector

Publié : mer. 01/juil./2015 15:38
par blendman
J'ai regardé ton lien, mais je ne sais toujours comment convertir pour que ça fonctionne avec mon exemple. Pourtant j'ai essayé toutes les formules, y compris ici :
http://www.rapidtables.com/convert/color/rgb-to-hsv.htm
http://www.easyrgb.com/index.php?X=MATH&H=20#text20

Et d'autres..
J'obtiens les bons résultats : saturation, hue et value, mais c'est après que je ne sais pas obtenir la couleur que je dois afficher (en fait, je ne sais pas quoi faire des valeurs H, S, V ^^)

Code : Tout sélectionner

Enumeration ; gadget
  #G_ColorSelector
  #G_ColorArcEnCielSelect
  #btn_Color
EndEnumeration

Enumeration ; image
  #IMAGE_ColorSelector
EndEnumeration

Structure sHsv
  h.f
  s.f
  v.f  
EndStructure

Global HSV.sHsv

Procedure.f Max3(Value1.f=0, Value2.f=0, Value3.f=0)
  Protected MaxValue.f = 0
  If Value1 > MaxValue : MaxValue = Value1 : EndIf
  If Value2 > MaxValue : MaxValue = Value2 : EndIf
  If Value3 > MaxValue : MaxValue = Value3 : EndIf
  ProcedureReturn MaxValue
EndProcedure
Procedure.f Min3(Value1.f=255, Value2.f=255, Value3.f=255)
  Protected MinValue.f = 255
  If Value1 < MinValue : MinValue = Value1 : EndIf
  If Value2 < MinValue : MinValue = Value2 : EndIf
  If Value3 < MinValue : MinValue = Value3 : EndIf
  ProcedureReturn MinValue
EndProcedure

Procedure RgbToHSV(r,g,b)
  
  R1.f = R
  R1/255    
  G1.f = G
  G1/255    
  B1.f = B
  B1/255
  
  Cmax.f = max3(R1, G1, B1)    
  Cmin.f = min3(R1, G1, B1)    
  delta.f = Cmax - Cmin
  
  
  ; Value calculation:  
  HSV\v = Cmax
  
  ; Saturation
  If Cmax <> 0 
    HSV\s = delta 
    HSV\s/ Cmax ;		// s
  Else 
    HSV\s = 0;
    HSV\h = -1;
    ProcedureReturn 
  EndIf
  
; HUE

If  Delta = 0  ;//This is a gray, no chroma...

   HSV\H = 0   ;//HSV results from 0 To 1
   HSV\S = 0

Else   ;//Chromatic Data...

   HSV\S = Delta / Cmax

   del_R.f = ( ( ( Cmax - R1 ) / 6 ) + ( Delta / 2 ) ) / Delta
   del_G.f = ( ( ( Cmax - G1 ) / 6 ) + ( Delta / 2 ) ) / Delta
   del_B.f = ( ( ( Cmax - B1 ) / 6 ) + ( Delta / 2 ) ) / Delta

   If  R1 = Cmax  
     HSV\H = del_B - del_G
   ElseIf G1 = Cmax  
     HSV\H = ( 1 / 3 ) + del_R - del_B
   ElseIf  B1 = Cmax  
     HSV\H = ( 2 / 3 ) + del_G - del_R
   EndIf
   
   If  HSV\H < 0  
     HSV\H + 1
   EndIf
   If  HSV\H > 1  
     HSV\H - 1
   EndIf
   
   
           
EndIf
  
  
  HSV\h * 360  ; on rétablit en degrés pour avoir la bonne valeur
  If HSV\h < 0 
    HSV\h + 360
  EndIf
       
EndProcedure





Procedure SetColorSelector(color,x=0,y=0)
  
  Shared cursorX,cursorY
  
  R = Red(color)
  G = Green(color)
  B = Blue(color)
  
  
  If R <> 0 And G <> 0 And B <>  0
        
   RGBtoHSV(r,g,b)
   
   ; ça, c'est ok 
    Debug StrF(HSV\H,3)+"/"+StrF(HSV\V,3) + "/"+StrF(HSV\S,3)
    
    
    ; ça c'est pas ok du tout.
    h = (HSV\h*RGB(255,255,255)) * HSV\s
    h/360
    
    ; HueToRGB() ??
    
    R = Red(h)
    G = Green(h)
    B = Blue(h)
    
  EndIf
  
  
  
  If StartDrawing(ImageOutput(#IMAGE_ColorSelector))
    Box(0,0,256,256,RGBA(255,255,255,255))   
    DrawingMode(#PB_2DDrawing_AlphaBlend)
    For i = 0 To 255
      For j = 0 To 255
        Plot(i, j, RGBA($FF, $FF, $FF, i))
        Plot(i, j, RGBA(0, 0, 0, j))
      Next
    Next     
    For i = 0 To 255
      For j = 0 To 255         
        Plot(i, j, RGBA(R, G, B, i))
        Plot(i, j, RGBA(0, 0, 0, j))
      Next
    Next
    StopDrawing()
  EndIf
  
  If StartDrawing(CanvasOutput(#G_ColorSelector))
    Box(0,0,256,256,RGB(255,255,255))   
    DrawingMode(#PB_2DDrawing_AlphaBlend)
    DrawImage(ImageID(#IMAGE_ColorSelector),0,0,GadgetWidth(#G_ColorSelector),GadgetHeight(#G_ColorSelector))
    If mode =1
      DrawingMode(#PB_2DDrawing_Outlined)
      Circle(x,y,8,#White)
      Circle(x,y,9,#Black)
      cursorX = x
      cursorY = y
    Else
      DrawingMode(#PB_2DDrawing_Outlined)
      Circle(cursorX,cursorY,8,#White)
      Circle(cursorX,cursorY,9,#Black)
    EndIf   
    StopDrawing()
    
  EndIf
  
EndProcedure

OpenWindow(0, 0, 0, 600,400, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

CreateImage(#IMAGE_ColorSelector,256,256)
CanvasGadget(#G_ColorSelector,10,10,256,256)
SetColorSelector(RGB(255,0,0))

ButtonGadget(#btn_Color, 300,10,100,50,"Change color")

Repeat
  
  event = WaitWindowEvent(1)
  
  Select event
      
    Case #PB_Event_Gadget
      Select EventGadget()
        Case  #btn_Color
          Color = ColorRequester(color)
          SetColorSelector(color)
      EndSelect
      Select EventType()
        Case  #PB_EventType_LeftClick
          
          cursorX = WindowMouseX(0)-4 ; -4 pour essayer de centrer
          cursorY = WindowMouseY(0)- 4
          SetColorSelector (color,cursorX ,cursorY )
      EndSelect
      
  EndSelect
  
Until Event = #PB_Event_CloseWindow

Re: RGB et color selector

Publié : mer. 01/juil./2015 16:48
par Mesa
Il y a des codes ici:
http://www.purearea.net/pb/CodeArchiv/G ... SVtoRGB.pb

et là
Colormodels: RGB, CMY, HLS, HSL (HLS, HSI)
http://www.purebasic.fr/english/viewtopic.php?t=23783

C'est ce que tu cherches ?

M.

Re: RGB et color selector

Publié : mer. 01/juil./2015 17:05
par blendman
Mesa a écrit :C'est ce que tu cherches ?
Hélas, je connais déjà ces codes et ce n'est pas ce que je cherche tout à fait.
Je suis parvenu à coder un RgbToHSv(), et j'obtiens les bons résultats (H,S,V), mais ce que je ne trouve pas c'est comment ensuite actualiser mon color selector avec la bonne teinte (uniquement) :
en gros je voudrais trouver un HueToRGB(), mais je ne trouve pas :(


Que dois-je faire avec les couleurs H, S et V pour avoir l'équivalent de H uniquement ?

Dans mon code, j'obtiens :

Code : Tout sélectionner

 
RGBtoHSV(r,g,b)
Debug StrF(HSV\H,3)+"/"+StrF(HSV\V,3) + "/"+StrF(HSV\S,3) ; ça, c'est ok 

; la suite n'est pas ok du tout.
; H?? -> HSV\h c'est par rapport à 360°, RGB c'est par rapport à RGB(255,255,255)  ?
h = (HSV\h*RGB(255,255,255))
h/360
    
; HueToRGB() ??
R = Red(h)
G = Green(h)
B = Blue(h)
rgb(R,G,B) devrait me donner la même couleur que la teinte HSV\h obtenue, mais ce n'est pas le cas.
(voir mon code le message précédent)

Re: RGB et color selector

Publié : mer. 01/juil./2015 17:35
par blendman
Merci D.. heu Spock, je vais regarder ça (j'ai trouvé ses formules, j'étais en train de les adapter ^^)
Le HueToRgb(), en fait, il s'en sert dans HSLtoRGB(), donc, tel quel, je ne pourrais pas m'en servir.

Mais en fait, pour obtenir une couleur RGB à partir d'un hue, il fallait tout simplement que je mette la luminosité à 100% et la saturation dans HsvToRGB() :

Dites-moi si ça vous semble correct ce code (je pense que oui, mais je ne suis pas certain ^^) :

Code : Tout sélectionner

Enumeration ; gadget
  #G_ColorSelector
  #G_ColorArcEnCielSelect
  #btn_Color
EndEnumeration

Enumeration ; image
  #IMAGE_ColorSelector
EndEnumeration

Structure sHsv
  h.f
  s.f
  v.f  
EndStructure
Structure Colour
  R.f
  G.f
  B.f  
EndStructure
Global HSV.sHsv

Procedure.f Max3(Value1.f=0, Value2.f=0, Value3.f=0)
  Protected MaxValue.f = 0
  If Value1 > MaxValue : MaxValue = Value1 : EndIf
  If Value2 > MaxValue : MaxValue = Value2 : EndIf
  If Value3 > MaxValue : MaxValue = Value3 : EndIf
  ProcedureReturn MaxValue
EndProcedure
Procedure.f Min3(Value1.f=255, Value2.f=255, Value3.f=255)
  Protected MinValue.f = 255
  If Value1 < MinValue : MinValue = Value1 : EndIf
  If Value2 < MinValue : MinValue = Value2 : EndIf
  If Value3 < MinValue : MinValue = Value3 : EndIf
  ProcedureReturn MinValue
EndProcedure

Procedure RgbToHSV(r,g,b)
  
  R1.f = R
  R1/255    
  G1.f = G
  G1/255    
  B1.f = B
  B1/255
  
  Cmax.f = max3(R1, G1, B1)    
  Cmin.f = min3(R1, G1, B1)    
  delta.f = Cmax - Cmin
  
  
  ; Value calculation:  
  HSV\v = Cmax
  
  ; Saturation
  If Cmax <> 0 
    HSV\s = delta 
    HSV\s/ Cmax ;		// s
  Else 
    HSV\s = 0;
    HSV\h = -1;
    ProcedureReturn 
  EndIf
  
; HUE

If  Delta = 0  ;//This is a gray, no chroma...

   HSV\H = 0   ;//HSV results from 0 To 1
   HSV\S = 0

Else   ;//Chromatic Data...

   HSV\S = Delta / Cmax

   del_R.f = ( ( ( Cmax - R1 ) / 6 ) + ( Delta / 2 ) ) / Delta
   del_G.f = ( ( ( Cmax - G1 ) / 6 ) + ( Delta / 2 ) ) / Delta
   del_B.f = ( ( ( Cmax - B1 ) / 6 ) + ( Delta / 2 ) ) / Delta

   If  R1 = Cmax  
     HSV\H = del_B - del_G
   ElseIf G1 = Cmax  
     HSV\H = ( 1 / 3 ) + del_R - del_B
   ElseIf  B1 = Cmax  
     HSV\H = ( 2 / 3 ) + del_G - del_R
   EndIf
   
   If  HSV\H < 0  
     HSV\H + 1
   EndIf
   If  HSV\H > 1  
     HSV\H - 1
   EndIf
   
   
           
EndIf
  
  
  HSV\h * 360  ;				// degrees
  If HSV\h < 0 
    HSV\h + 360
  EndIf
  
    
  
EndProcedure

Procedure.f MinF(n1.f, n2.f) 
  If n1<n2 
    ProcedureReturn n1 
  EndIf 
  ProcedureReturn n2 
EndProcedure 
Procedure.f MaxF(n1.f, n2.f) 
  If n1>n2 
    ProcedureReturn n1 
  EndIf 
  ProcedureReturn n2 
EndProcedure 

Procedure.i HSV2RGB(H.f,S.f,V.f) 
  
  Define.COLOUR  sat 

    While h < 0 
        h = h + 360 
    Wend 
    
    While h > 360 
        h = h - 360 
    Wend 

    If h < 120 
        sat\r = (120 - h) / 60.0 
        sat\g = h / 60.0 
        sat\b = 0 
    ElseIf h < 240 
        sat\r = 0 
        sat\g = (240 - h) / 60.0 
        sat\b = (h - 120) / 60.0 
    Else 
        sat\r = (h - 240) / 60.0 
        sat\g = 0 
        sat\b = (360 - h) / 60.0 
    EndIf 
    
    sat\r = MinF(sat\r, 1) 
    sat\g = MinF(sat\g, 1) 
    sat\b = MinF(sat\b, 1) 

    r = ((1 - s + s * sat\r) * v )*255
    g = ((1 - s + s * sat\g) * v )*255
    b = ((1 - s + s * sat\b) * v )*255
    
    Debug "RGB (d'après la teinte) : " + Str(R)+"/"+Str(G)+"/"+Str(B)
    
    ProcedureReturn RGB(r,g,b)    
EndProcedure 



Procedure SetColorSelector(color,x=0,y=0,mode=0)
  
  Shared cursorX,cursorY
  
  R = Red(color)
  G = Green(color)
  B = Blue(color)
    
  
  RGBtoHSV(r,g,b)  
  ; ça, c'est ok 
  Debug StrF(HSV\H,3)+"/"+StrF(HSV\V,3) + "/"+StrF(HSV\S,3)
  
  H = HSV2RGB(HSV\H,1,1) 
  
  R = Red(h)
  G = Green(h)
  B = Blue(h)
  
  If mode = 0
    
    cursorX = 256 * HSV\s
    cursorY = 256-256 * HSV\v
    ; Debug "pos : "+Str(cursorX)+"/"+Str(cursorY)
  EndIf
  
  If StartDrawing(ImageOutput(#IMAGE_ColorSelector))
    Box(0,0,256,256,RGBA(255,255,255,255))   
    DrawingMode(#PB_2DDrawing_AlphaBlend)
    For i = 0 To 255
      For j = 0 To 255
        Plot(i, j, RGBA($FF, $FF, $FF, i))
        Plot(i, j, RGBA(0, 0, 0, j))
      Next
    Next     
    For i = 0 To 255
      For j = 0 To 255         
        Plot(i, j, RGBA(R, G, B, i))
        Plot(i, j, RGBA(0, 0, 0, j))
      Next
    Next
    StopDrawing()
  EndIf
  
  If StartDrawing(CanvasOutput(#G_ColorSelector))
    Box(0,0,256,256,RGB(255,255,255))   
    DrawingMode(#PB_2DDrawing_AlphaBlend)
    DrawImage(ImageID(#IMAGE_ColorSelector),0,0,GadgetWidth(#G_ColorSelector),GadgetHeight(#G_ColorSelector))
    If mode =1
      DrawingMode(#PB_2DDrawing_Outlined)
      Circle(x,y,8,#White)
      Circle(x,y,9,#Black)
      cursorX = x
      cursorY = y
    Else
      DrawingMode(#PB_2DDrawing_Outlined)
      Circle(cursorX,cursorY,8,#White)
      Circle(cursorX,cursorY,9,#Black)
    EndIf   
    StopDrawing()
    
  EndIf
  
EndProcedure

OpenWindow(0, 0, 0, 600,400, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

CreateImage(#IMAGE_ColorSelector,256,256)
CanvasGadget(#G_ColorSelector,10,10,256,256)
SetColorSelector(RGB(255,0,0))

ButtonGadget(#btn_Color, 300,10,100,50,"Change color")

Repeat
  
  event = WaitWindowEvent(1)
  
  Select event
      
    Case #PB_Event_Gadget
      Select EventGadget()
        Case  #btn_Color
          Color = ColorRequester(color)
          SetColorSelector(color)
          
        Case #G_ColorSelector
          Select EventType()
            Case  #PB_EventType_LeftButtonUp
              get = 0
            Case  #PB_EventType_MouseMove
              If get = 1
                cursorX = WindowMouseX(0)- 8 
                cursorY = WindowMouseY(0)- 8
                SetColorSelector (color,cursorX ,cursorY,1)
              EndIf
              
            Case  #PB_EventType_LeftButtonDown 
              GEt = 1             
              cursorX = WindowMouseX(0)- 8 
              cursorY = WindowMouseY(0)- 8
              SetColorSelector (color,cursorX ,cursorY,1)
          EndSelect
          
      EndSelect
  EndSelect
  
Until Event = #PB_Event_CloseWindow

MAintenant, il ne reste plus qu'à bien placer le curseur en fonction de la couleur choisie ^^
EDIT / c'est ok, j'ai trouvé (enfin, je crois. J4ai mis le code à jour (dans ce message-ci)