Change color brightness by percentage?

Just starting out? Need help? Post your questions and find answers here.
Dude
Addict
Addict
Posts: 1907
Joined: Mon Feb 16, 2015 2:49 pm

Change color brightness by percentage?

Post by Dude »

I've been trying to figure out how to change a given color value by a percent, be it higher or lower. I'm crap at maths so nothing I try is working in all situations. :(

I had a brown color that when I used -50 as the percent, it does get 50% darker, but if I use -5 as the percent, instead of just being a little bit darker, the brown turns to pink!

So can any brainy maths people help me with this? I just want a procedure that I can call like: newcolor=ColorPercent(origcolor,percent), where percent can be a negative number to darken, or positive to brighten.

BTW, here's some test code to show the problem:

Code: Select all

Procedure.f ColorPercent(color.f,percent.f)
  If percent>0 ; Brighten.
    new.f=color+Abs(((percent/100)*color))
  Else ; Darken.
    new.f=color-Abs(((percent/100)*color))
  EndIf
  ProcedureReturn new
EndProcedure

OpenWindow(0,200,200,150,70,"test",#PB_Window_SystemMenu)

color=13824250 ; Brown.

CreateImage(1,50,50,32,color)
CreateImage(2,50,50,32,ColorPercent(color,-50))

ImageGadget(1,10,10,50,50,ImageID(1))
ImageGadget(2,80,10,50,50,ImageID(2))

Repeat : Until WaitWindowEvent()=#PB_Event_CloseWindow
Last edited by Dude on Mon Jan 15, 2018 12:15 pm, edited 1 time in total.
walbus
Addict
Addict
Posts: 929
Joined: Sat Mar 02, 2013 9:17 am

Re: Change color brightness by percentage?

Post by walbus »

@Dude
You can looking in the BucketFill advanced (BF) code for the function "Image_coloring_BF"
This function works percent based, also for contrast and brightness

But, i am also nterested for other, very fast, ASM based solutions !
infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Change color brightness by percentage?

Post by infratec »

In general:

You have to convert the RGB value to a format which represents also the brightness.

Then you can change the brightness and convert it back to RGB.

http://www.purebasic.fr/english/viewtop ... 13&t=69317

Bernd
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4636
Joined: Sun Apr 12, 2009 6:27 am

Re: Change color brightness by percentage?

Post by RASHAD »

#1 :

Code: Select all

Procedure ColorPercent(color,percent)
  nred = Red(color) + percent
  If nred > 255 :nred = 255 : EndIf
  If nred < 0 : nred = 0 : EndIf
  ngreen = Green(color) + percent
  If ngreen > 255 :ngreen = 255 : EndIf
  If ngreen < 0 : ngreen = 0 : EndIf
  nblue = Blue(color) + percent
  If nblue > 255 :nblue = 255 : EndIf
  If nblue < 0 : nblue = 0 : EndIf
  ncolor = RGB(nred,ngreen,nblue)
  ProcedureReturn ncolor
EndProcedure

OpenWindow(0,0,0,400,100,"test",#PB_Window_SystemMenu |#PB_Window_ScreenCentered)

color=$0000FF

TextGadget(1,10,10,50,50,"")
SetGadgetColor(1,#PB_Gadget_BackColor ,color)
TextGadget(2,340,10,50,50,"")
SetGadgetColor(2,#PB_Gadget_BackColor ,color)
TrackBarGadget(3,5,70 ,390,20,0,510)
SetGadgetState(3,255)
Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Quit = 1
      
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 3
          percent = GetGadgetState(3) - 255
          ncolor = ColorPercent(color,percent)
          SetGadgetColor(2,#PB_Gadget_BackColor ,ncolor)
      EndSelect
  EndSelect
Until Quit = 1
#2 :

Code: Select all

Procedure BrightnessRGB(RGB_Color.l, Delta.w)
  !XOR Edx, Edx 
  !XOR Ebx, Ebx
  !XOR Ecx, Ecx
  !MOV BX, Word [p.v_Delta]
  !MOV Eax, dWord [p.v_RGB_Color]
  !MOV DL, AL
  !CALL .adddelta
  !MOV CL, DL
  !MOV DL, AH 
  !CALL .adddelta
  !MOV CH, DL
  !BSWAP Eax 
  !MOV DL, AH
  !CALL .adddelta
  !MOV AH, DL
  !BSWAP Eax 
  !MOV AX, CX 
  !JMP .ready
  !.adddelta:
  !ADD DX, BX
  !BT DX, 15 
  !JC .negativ 
  !CMP DX, $FF
  !JBE .inrange
  !.bigger:
  !MOV DX, $00FF
  !JMP .inrange 
  !.negativ:
  !XOR Edx, Edx
  !.inrange:
  !RET
  !.ready:
  ProcedureReturn 
EndProcedure 

OpenWindow(0,0,0,400,100,"test",#PB_Window_SystemMenu |#PB_Window_ScreenCentered)

color=$0000FF

TextGadget(1,10,10,50,50,"")
SetGadgetColor(1,#PB_Gadget_BackColor ,color)
TextGadget(2,340,10,50,50,"")
SetGadgetColor(2,#PB_Gadget_BackColor ,color)
TrackBarGadget(3,5,70 ,390,20,0,510)
SetGadgetState(3,255)
Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Quit = 1
      
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 3
          percent = GetGadgetState(3) - 255
          ncolor = BrightnessRGB(color,percent)
          SetGadgetColor(2,#PB_Gadget_BackColor ,ncolor)
      EndSelect
  EndSelect
Until Quit = 1
Egypt my love
davido
Addict
Addict
Posts: 1890
Joined: Fri Nov 09, 2012 11:04 pm
Location: Uttoxeter, UK

Re: Change color brightness by percentage?

Post by davido »

@Dude,
Great question, Thank you.

@RASHAD,
Must admit to having a go myself. Failed miserably! So its nice to see....
Looks like another, nice solution. :D
I've added a couple of extra text gadgets to see the changes in hex:

Code: Select all

Procedure ColorPercent(color,percent)
  nred = Red(color) + percent
  If nred > 255 :nred = 255 : EndIf
  If nred < 0 : nred = 0 : EndIf
  ngreen = Green(color) + percent
  If ngreen > 255 :ngreen = 255 : EndIf
  If ngreen < 0 : ngreen = 0 : EndIf
  nblue = Blue(color) + percent
  If nblue > 255 :nblue = 255 : EndIf
  If nblue < 0 : nblue = 0 : EndIf
  ncolor = RGB(nred,ngreen,nblue)
  ProcedureReturn ncolor
EndProcedure

OpenWindow(0,0,0,400,100,"test",#PB_Window_SystemMenu |#PB_Window_ScreenCentered)

color=$004BAA

TextGadget(1,10,10,50,50,"")
SetGadgetColor(1,#PB_Gadget_BackColor ,color)
TextGadget(2,340,10,50,50,"")
SetGadgetColor(2,#PB_Gadget_BackColor ,color)
TrackBarGadget(3,5,70 ,390,20,0,510)
SetGadgetState(3,255)
TextGadget(12,70,30,70,20,RSet(Hex(color),6,"0"))
TextGadget(13,280,30,70,20,RSet(Hex(color),6,"0"))
Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Quit = 1
      
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 3
          percent = GetGadgetState(3) - 255
          ncolor = ColorPercent(color,percent)
          SetGadgetColor(2,#PB_Gadget_BackColor ,ncolor)
          SetGadgetText(13,RSet(Hex(ncolor),6,"0"))
      EndSelect
  EndSelect
Until Quit = 1
It appears to me that it works very well until a point is reached where one of the colours becomes $00 or $FF.
DE AA EB
walbus
Addict
Addict
Posts: 929
Joined: Sat Mar 02, 2013 9:17 am

Re: Change color brightness by percentage?

Post by walbus »

@Davido
These solutions are always the same, because they do ever the same
You can find thousands of times on the internet, always the same
So also my "Nice Solution", I didn't invent it :wink:
Last edited by walbus on Mon Jan 15, 2018 5:46 pm, edited 1 time in total.
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: Change color brightness by percentage?

Post by wilbert »

SSE based brightness adjustment

Code: Select all

Procedure AdjustBrightness(Color, Delta)
  !movd xmm0, [p.v_Color]
  !movd xmm2, [p.v_Delta]
  !pxor xmm1, xmm1
  !punpcklbw xmm0, xmm1
  !pshuflw xmm2, xmm2, 0
  !psrlq xmm2, 16
  !paddsw xmm0, xmm2
  !packuswb xmm0, xmm0
  !movd eax, xmm0
  ProcedureReturn
EndProcedure
Windows (x64)
Raspberry Pi OS (Arm64)
walbus
Addict
Addict
Posts: 929
Joined: Sat Mar 02, 2013 9:17 am

Re: Change color brightness by percentage?

Post by walbus »

Nice to see other solutions
Last edited by walbus on Tue Jan 16, 2018 8:23 am, edited 1 time in total.
davido
Addict
Addict
Posts: 1890
Joined: Fri Nov 09, 2012 11:04 pm
Location: Uttoxeter, UK

Re: Change color brightness by percentage?

Post by davido »

@walbus,
Sadly, you are probably correct; it's hard to be original. :)
However, I always think it is nice to thank others for the time and effort they have put in.
DE AA EB
Dude
Addict
Addict
Posts: 1907
Joined: Mon Feb 16, 2015 2:49 pm

Re: Change color brightness by percentage?

Post by Dude »

Thanks everyone, but especially Rashad who is always so helpful and quick to reply to me. I really appreciate it, man. :D
User avatar
captain_skank
Enthusiast
Enthusiast
Posts: 636
Joined: Fri Oct 06, 2006 3:57 pm
Location: England

Re: Change color brightness by percentage?

Post by captain_skank »

This is what i use - but it's just a 'shade' of the same colour and not optimised in any way whatsoever :)

Code: Select all

Procedure darker_shade(PVAR_rgb.i, PVAR_percentage.i)
  
  LVAR_r.i = Red(PVAR_rgb)
  LVAR_g.i = Green(PVAR_rgb)
  LVAR_b.i = Blue(PVAR_rgb)
  LVAR_p.d = PVAR_percentage / 100
  
  ProcedureReturn RGB(LVAR_r * LVAR_p, LVAR_g * LVAR_p, LVAR_b * LVAR_p)
  
EndProcedure



If OpenWindow(0, 0, 0, 220, 520, "CanvasGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    CanvasGadget(0, 10, 10, 200, 500)
    
    LVAR_r.i = 0
    LVAR_g.i = 255
    LVAR_b.i = 0
    LVAR_percentage.i = 100
    
    
    If StartDrawing(CanvasOutput(0))
      For LVAR_loop = 0 To 450 Step 50
        If LVAR_percentage = 100
          Box(0, LVAR_loop, 200, 50, RGB(LVAR_r, LVAR_g, LVAR_b))
          DrawText(10,LVAR_loop + 10, Str(LVAR_percentage) + "%",$FFFFFF, RGB(LVAR_r, LVAR_g, LVAR_b))
          LVAR_percentage - 5
        Else
          Box(0, LVAR_loop, 200, 50, darker_shade(RGB(LVAR_r, LVAR_g, LVAR_b), LVAR_percentage))
          DrawText(10,LVAR_loop + 10, Str(LVAR_percentage) + "%",$FFFFFF, darker_shade(RGB(LVAR_r, LVAR_g, LVAR_b), LVAR_percentage))
          LVAR_percentage - 5
        EndIf
      Next

      StopDrawing()
    EndIf
    
    Repeat
      Event = WaitWindowEvent()
          
      If Event = #PB_Event_Gadget And EventGadget() = 0 
        If EventType() = #PB_EventType_LeftButtonDown Or (EventType() = #PB_EventType_MouseMove And GetGadgetAttribute(0, #PB_Canvas_Buttons) & #PB_Canvas_LeftButton)
          If StartDrawing(CanvasOutput(0))
            x = GetGadgetAttribute(0, #PB_Canvas_MouseX)
            y = GetGadgetAttribute(0, #PB_Canvas_MouseY)
            Circle(x, y, 10, RGB(Random(255), Random(255), Random(255)))
            StopDrawing()
          EndIf
        EndIf
      EndIf    
      
    Until Event = #PB_Event_CloseWindow
  EndIf
Post Reply