Page 1 of 1

[ok] Find RGB color from Hue

Posted: Wed Jul 01, 2015 1:12 pm
by [blendman]
Hi

For my application, I need to use a color selector. I can pick the color from an image/sprite, and I would like to update the color selector with the good color (not the RGB color, but the RGB from the hue color ^^).

I have found thousand of code conversion, but I haven't foudn a simple solution for my problem.

Here is the code :

[Edit : ok, I have found ^^]
Code modified :

Code: Select all

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
Thanks ;)