Page 1 sur 1

Test sélecteur de couleur en cercle

Publié : mar. 30/mars/2021 22:06
par GallyHC
Bonjour,

Il y avait un bout de temps que j'avais l'idée de faire un test de sélecteur de couleur en cercle (et cela fait quelques temps que je n'avais pas fait de code en PB). Je me suis enfin mis dessus ce soir et cela donne ce test (code sale, pas optimisé, etc...), mais je vous le partage pour avoir vos avis.

Ce n'est pas encore un sélecteur de couleur mais juste l'affichage du cercle (je précise on sais jamais ^^).

Code : Tout sélectionner

EnableExplicit

; ****************************************************************************

Enumeration
  #Window
  #Canvas
  #Track
EndEnumeration

; ****************************************************************************

#DEFINE_SINCOS_MAX  = 359

Define.i i
Global Dim _Sin.f   (#DEFINE_SINCOS_MAX)
Global Dim _Cos.f   (#DEFINE_SINCOS_MAX)
For i=0 To #DEFINE_SINCOS_MAX
  _Sin(i) = Sin((i / 180) * #PI)
  _Cos(i) = Cos((i / 180) * #PI)
Next i

; ****************************************************************************

Procedure.l _CONVERTRM(fM1.f, fM2.f, fCH.f)
  
  If fCH > 360
    fCH - 360
  ElseIf fCH < 0
    fCH + 360
  EndIf
  If fCH < 60
    fM1 = fM1 + (fM2 - fM1) * fCH / 60
  ElseIf fCH < 180
    fM1 = fM2
  ElseIf fCH < 240
    fM1 = fM1 + (fM2 - fM1) * (240 - fCH) / 60
  EndIf
  
  ProcedureReturn fM1 * 255

EndProcedure
  
Procedure _HSL_TO_RGB(fCH.f, fCL.f, fCS.f, *bCR, *bCG, *bCB)
  
  Protected.f fM1, fM2
  
  fCH = fCH * 360 / 255
  fCL = fCL       / 255
  fCS = fCS       / 255
  If fCL < 0.5
    fM2 = fCL + fCL * fCS
  Else
    fM2 = fCL + fCS - fCL * fCS
  EndIf
  fM1 = 2 * fCL - fM2
  
  If fCS = 0
    PokeL(*bCR, fCL * 255)
    PokeL(*bCG, fCL * 255)
    PokeL(*bCB, fCL * 255)
  Else
    PokeL(*bCR, _CONVERTRM(fM1, fM2, fCH + 120))
    PokeL(*bCG, _CONVERTRM(fM1, fM2, fCH      ))
    PokeL(*bCB, _CONVERTRM(fM1, fM2, fCH - 120))
  EndIf

EndProcedure

; ****************************************************************************

Procedure DrawCircular(radius, cs.l = 255)
  
  Define.l i, j, k, x, y, x1, y1, x2, y2, x3, y3, x4, y4
  Define.l cr, cg, cb, cl, ch
  radius / 2
  Define.f fpas = 255 / radius
  Define.f dpas = 255 / #DEFINE_SINCOS_MAX
  
  If StartVectorDrawing(CanvasVectorOutput(#Canvas))
    For j = 0 To radius
      cl = j * fpas
      For i = 0 To #DEFINE_SINCOS_MAX Step #DEFINE_SINCOS_MAX / 48
        ch = i * dpas
        x1 = radius + _Sin(i) * (radius - j)
        y1 = radius + _Cos(i) * (radius - j)
        x2 = radius + _Sin((i + (#DEFINE_SINCOS_MAX) / 48) % #DEFINE_SINCOS_MAX) * (radius - j)
        y2 = radius + _Cos((i + (#DEFINE_SINCOS_MAX) / 48) % #DEFINE_SINCOS_MAX) * (radius - j)
        
        x3 = radius + _Sin(i) * (radius - j - (radius / (24 - 1)))
        y3 = radius + _Cos(i) * (radius - j - (radius / (24 - 1)))
        x4 = radius + _Sin((i + ((#DEFINE_SINCOS_MAX) / 48) + 2) % #DEFINE_SINCOS_MAX) * (radius - j - 1 - (radius / (24 - 1)))
        y4 = radius + _Cos((i + ((#DEFINE_SINCOS_MAX) / 48) + 2) % #DEFINE_SINCOS_MAX) * (radius - j - 1 - (radius / (24 - 1)))

        _HSL_TO_RGB (ch, cl, cs , @cr, @cg, @cb)
        
        VectorSourceColor(RGBA(cr, cg, cb, 255))
        MovePathCursor  (x1, y1)
        AddPathLine     (x3, y3)
        AddPathLine     (x4, y4)
        AddPathLine     (x2, y2)
        FillPath        ()
      Next i
      j + ((radius / 24) - 1)
    Next j
    StopVectorDrawing ()
  EndIf

EndProcedure

; ****************************************************************************

Define.i save, event, eveng, radius = 600
  
If OpenWindow(#Window, 0, 0, radius + 1, radius + 50, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  CanvasGadget(#Canvas, 0, 0, radius, radius, #PB_Canvas_Keyboard)
  TrackBarGadget(#Track, 0,  radius + 10, radius, 30, 0, 255)
  SetGadgetState(#Track, 255)

  DrawCircular(radius)  
  Repeat
    event = WaitWindowEvent()
    eveng = EventGadget()
    
    Select eveng 
      Case #Canvas
      Case #Track
        If save <> GetGadgetState(#Track)
          save = GetGadgetState(#Track)
          DrawCircular(radius, GetGadgetState(#Track))
        EndIf
    EndSelect
    
  Until Event = #PB_Event_CloseWindow
EndIf

End
Cordialement,
GallyHC

Re: Test sélecteur de couleur en cercle

Publié : mar. 30/mars/2021 23:22
par case
sympa pour du code sale,mal optimisé, toussa toussa

Re: Test sélecteur de couleur en cercle

Publié : mer. 31/mars/2021 8:37
par MLD
Salut Gally
C'est un bon début. :lol:
Tu pourrait ajouter un curseur transparence.
Je suppose que le code couleur sera transmis par le presse papier. ou/et par l'intégration dans PB :?:

Re: Test sélecteur de couleur en cercle

Publié : mer. 31/mars/2021 8:42
par SPH
Très sympa. Mais toutes les couleurs sont elles représentées ?

(je pense qu'il y a de nombreux doublons) :idea:

Re: Test sélecteur de couleur en cercle

Publié : mer. 31/mars/2021 9:05
par GallyHC
Bonjour,

@MLD > Oui pour l'ajout de la transparence c'est une bonne idée et ce sera si je vais au bout un module donc qui renvoie la valeur.

@SPH > Le code est juste un test fait hier soir donc pas encore tout fait ni même vérifié (le reste des couleurs est aussi avec le trackbar), je ne vois pas trop pour les doublons ?

Cordialement,
GallyHC

Re: Test sélecteur de couleur en cercle

Publié : mer. 31/mars/2021 9:29
par Ar-S
Le rendu est joli. Par contre je le trouve bien trop volumineux.
Le basculement vers le NB via la trackbar est trés cool.

Re: Test sélecteur de couleur en cercle

Publié : mer. 31/mars/2021 9:30
par SPH
Les doublons : j'ai copier coller l'image dans un logiciel d'image (photofiltre) et en zoomant, on y vois des polygones a 4 cotés dont les points sont de la même couleurs.

Mais bravo, j'applaudis l'exploit car je ne saurais pas faire pareil...

Re: Test sélecteur de couleur en cercle

Publié : mer. 31/mars/2021 9:43
par GallyHC
Bonjour,

Ar-S > oui, la taille est pour l'exemple pour vérifier que l'affichage soit correct. Change la valeur de "Define.i save, event, eveng, radius = 600".

SPH > oui mais ce n'est pas des doublons c'est juste un pas pour l'affichage.

Cordialement,
GallyHC

Re: Test sélecteur de couleur en cercle

Publié : mer. 31/mars/2021 15:55
par blendman
Salut

C'est très chouette. Par contre en créant des polygons comme ça, tu ne perds pas des nuances de couleurs du coup (les couleurs très proches entre elles) ?

Une version en luminosité/saturation (HSV) serait aussi très intéressante : le sélecteur de couleur saturé d'un coté (donc pas de blanc ni de noir à l'extérieur si la luminosité est à fond), et un rectangle allongé pour la luminosité.

le cercle avec les couleurs ressemble à ça :
Image

Un cercle couleur avec en bas un trackbar ou un rectangle où on voit la luminosité :
Image

ou comme ceci (dans blender) :
Image

Si tu fais une version comme ça, je m'en servirai sans doute dans certains de mes logiciels de dessins :)

Re: Test sélecteur de couleur en cercle

Publié : mer. 31/mars/2021 21:28
par venom
Zé beau...
Sympa GallyHC, un bon début. :wink:





@++

Re: Test sélecteur de couleur en cercle

Publié : sam. 03/avr./2021 19:44
par kernadec
bsr à tous
@GallyHC merci pour le partage
Ajout le résultat dans titre de la fenêtre
je pensais qu'avec
je pensais qu'avec un DrawingMode(#PB_2DDrawing_AlphaBlend)
que l'on obtiendrait la couleur Alpha(Point(x,y))...euuhhhh
apparemment ça ne marche pas? si quelqu'un a la combine.. 8O
Reste le Track pour ajuster manuellement l'alpha :D
Cordialement
Mis à jours le 4/4/2021

Code : Tout sélectionner

EnableExplicit

; ****************************************************************************

Enumeration
  #Window
  #Canvas
  #Track
EndEnumeration

; ****************************************************************************

#DEFINE_SINCOS_MAX  = 359

Define.i i
Global Dim _Sin.f   (#DEFINE_SINCOS_MAX)
Global Dim _Cos.f   (#DEFINE_SINCOS_MAX)

For i=0 To #DEFINE_SINCOS_MAX
  _Sin(i) = Sin((i / 180) * #PI)
  _Cos(i) = Cos((i / 180) * #PI)
Next i

; ****************************************************************************

Procedure.l _CONVERTRM(fM1.f, fM2.f, fCH.f)
  
  If fCH > 360
    fCH - 360
  ElseIf fCH < 0
    fCH + 360
  EndIf
  If fCH < 60
    fM1 = fM1 + (fM2 - fM1) * fCH / 60
  ElseIf fCH < 180
    fM1 = fM2
  ElseIf fCH < 240
    fM1 = fM1 + (fM2 - fM1) * (240 - fCH) / 60
  EndIf
  
  ProcedureReturn fM1 * 255
  
EndProcedure

Procedure _HSL_TO_RGB(fCH.f, fCL.f, fCS.f, *bCR, *bCG, *bCB)
  
  Protected.f fM1, fM2
  
  fCH = fCH * 360 / 255
  fCL = fCL       / 255
  fCS = fCS       / 255
  If fCL < 0.5
    fM2 = fCL + fCL * fCS
  Else
    fM2 = fCL + fCS - fCL * fCS
  EndIf
  fM1 = 2 * fCL - fM2
  
  If fCS = 0
    PokeL(*bCR, fCL * 255)
    PokeL(*bCG, fCL * 255)
    PokeL(*bCB, fCL * 255)
  Else
    PokeL(*bCR, _CONVERTRM(fM1, fM2, fCH + 120))
    PokeL(*bCG, _CONVERTRM(fM1, fM2, fCH      ))
    PokeL(*bCB, _CONVERTRM(fM1, fM2, fCH - 120))
  EndIf
  
EndProcedure

; ****************************************************************************

Procedure DrawCircular(radius, cs.l = 255)
  
  Define.l i, j, k, x, y, x1, y1, x2, y2, x3, y3, x4, y4
  Define.l cr, cg, cb, cl, ch
  radius / 2
  Define.f fpas = 255 / radius
  Define.f dpas = 255 / #DEFINE_SINCOS_MAX
  
  If StartVectorDrawing(CanvasVectorOutput(#Canvas))
    For j = 0 To radius
      cl = j * fpas
      For i = 0 To #DEFINE_SINCOS_MAX Step #DEFINE_SINCOS_MAX / 48
        ch = i * dpas
        x1 = radius + _Sin(i) * (radius - j)
        y1 = radius + _Cos(i) * (radius - j)
        x2 = radius + _Sin((i + (#DEFINE_SINCOS_MAX) / 48) % #DEFINE_SINCOS_MAX) * (radius - j)
        y2 = radius + _Cos((i + (#DEFINE_SINCOS_MAX) / 48) % #DEFINE_SINCOS_MAX) * (radius - j)
        
        x3 = radius + _Sin(i) * (radius - j - (radius / (24 - 1)))
        y3 = radius + _Cos(i) * (radius - j - (radius / (24 - 1)))
        x4 = radius + _Sin((i + ((#DEFINE_SINCOS_MAX) / 48) + 2) % #DEFINE_SINCOS_MAX) * (radius - j - 1 - (radius / (24 - 1)))
        y4 = radius + _Cos((i + ((#DEFINE_SINCOS_MAX) / 48) + 2) % #DEFINE_SINCOS_MAX) * (radius - j - 1 - (radius / (24 - 1)))
        
        _HSL_TO_RGB (ch, cl, cs , @cr, @cg, @cb)
        
        VectorSourceColor(RGBA(cr, cg, cb, 255))
        MovePathCursor  (x1, y1)
        AddPathLine     (x3, y3)
        AddPathLine     (x4, y4)
        AddPathLine     (x2, y2)
        FillPath        ()
      Next i
      j + ((radius / 24) - 1)
    Next j
    StopVectorDrawing ()
  EndIf
  
EndProcedure

Procedure Couleur_Titre()
  Protected X, Y, Couleur, capture$, Red$, Green$, Blue$, Alpha$
  X = GetGadgetAttribute(#Canvas, #PB_Canvas_MouseX)
  Y = GetGadgetAttribute(#Canvas, #PB_Canvas_MouseY)
  If  StartDrawing(CanvasOutput(#canvas))
    DrawingMode(#PB_2DDrawing_AlphaBlend)
    couleur = Point(X,Y)
    red$   = Right("00" + Str(Red(Couleur)),3)
    Green$ = Right("00" + Str(Green(Couleur)),3)
    Blue$  = Right("00" + Str(Blue(Couleur)),3)
    Alpha$ = Right("00" + Str(GetGadgetState(#Track)),3)
  EndIf
  capture$ = "SELECTEUR COULEURS RGBA( " + Red$ + ", " + Green$ + ", " + Blue$ + ", " + Alpha$ +" )"
  SetWindowTitle(0,capture$)
  StopDrawing()
EndProcedure

; ****************************************************************************
Define.i save, event, eveng, radius = 580, x, y

If OpenWindow(#Window, 0, 0, radius + 4, radius + 50, "SELECTEUR COULEURS RGBA", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  CanvasGadget(#Canvas, 2, 2, radius + 2, radius + 2, #PB_Canvas_Keyboard)
  TrackBarGadget(#Track, 0,  radius + 10, radius, 30, 0, 255)
  SetGadgetState(#Track, 255)
  
  DrawCircular(radius)
  Repeat
    event = WaitWindowEvent()
    eveng = EventGadget()
    Select eveng
      Case #Canvas
      Case #Track
        If save <> GetGadgetState(#Track)
          save = GetGadgetState(#Track)
          DrawCircular(radius, GetGadgetState(#Track))
        EndIf
        Couleur_Titre()
    EndSelect 
    Select event
      Case #PB_Event_Gadget
        Select EventType() 
          Case #PB_EventType_LeftButtonDown
            If EventType() = #PB_EventType_LeftButtonDown Or EventType() = #PB_EventType_MouseMove
              Couleur_Titre()
            EndIf
        EndSelect 
    EndSelect
  Until Event = #PB_Event_CloseWindow
EndIf
End

Re: Test sélecteur de couleur en cercle

Publié : dim. 04/avr./2021 7:44
par Micoute
C'est curieux l'effet de deux couleurs qui se touchent, car l'œil donne l'impression qu'elles fusionnent.

Merci pour le partage.

Re: Test sélecteur de couleur en cercle

Publié : dim. 04/avr./2021 11:44
par GallyHC
Bonjour tous,

Bon déjà comme je le disais c'est juste un test pour le moment et on peut être beaucoup plus précis au niveau des couleur exemple :

Image
Après pour avoir la couleur et avoir plus de précision celle-ci doit être obtenu par calcul et non en prenant la couleur dans le cercle ^^.

Cordialement,
GallyHC