Changer la luminosité d'une couleur

Partagez votre expérience de PureBasic avec les autres utilisateurs.
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Changer la luminosité d'une couleur

Message par Le Soldat Inconnu »

Salut,

je continue de refaire ma librairie Effect en prenant en compte les nouvelles méthodes que j'ai découverte pour gérer les couleurs.

Après la modification de teinte http://www.purebasic.fr/french/viewtopi ... =6&t=11674
Voici une modification plus basique, le changement de la luminosité.

Le principe reste sensiblement le même que pour la modification de la teinte (voir le sujet dont le lien est ci dessus)

la première étape consiste à décomposer la couleur en 3 points :
- Nuance de blanc
- Nuance de noir
- Teinte

Ensuite, je modifie la nuance de noir et de blanc en fonction de la luminosité

Puis j’applique les nouvelles nuances de noir et de blanc à la teinte pour créer la nouvelle couleur.

Code : Tout sélectionner

; Auteur : Le Soldat Inconnu
; Version de PB : 4.50
;
; Explication du programme :
; Changer la satuation d'une couleur

Procedure ColorLuminosity2(Color, Luminosity.d) ; Change color luminisoty ( -1 <= Luminosity <= 1, Luminosity = -1 give black color, Luminosity = 1 give white color)
	Protected Rouge, Vert, Bleu, Gris, Rouge_Origine, Bleu_Origine, Vert_Origine, Alpha, a.d, Nuance_Blanc, Nuance_Noir, b.d, i, ii, Level.d
	
	If Luminosity > 1
		Luminosity = 1
	ElseIf Luminosity < -1
		Luminosity = -1
	EndIf
	
	Rouge = Color & $FF
	Vert = Color >> 8 & $FF
	Bleu = Color >> 16 & $FF
	Alpha = Color >> 24
	
	; Recherche de la teinte
	If Bleu >= Vert And Bleu >= Rouge And Bleu > 0
		a = 255 / Bleu
		Nuance_Noir = 255 - Bleu
		Bleu = 255
		Vert = a * Vert
		Rouge = a * Rouge
	ElseIf Vert >= Bleu And Vert >= Rouge And Vert > 0
		a = 255 / Vert
		Nuance_Noir = 255 - Vert
		Bleu = a * Bleu
		Vert = 255
		Rouge = a * Rouge
	ElseIf Rouge >= Vert And Rouge >= Bleu And Rouge > 0
		a = 255 / Rouge
		Nuance_Noir = 255 - Rouge
		Bleu = a * Bleu
		Vert = a * Vert
		Rouge = 255
	Else
		Nuance_Noir = 255
		Bleu = 255
		Vert = 255
		Rouge = 255
	EndIf
	
	If Bleu < Vert And Bleu < Rouge
		a = 1 -(Bleu / 255)
		Nuance_Blanc = 255 - Bleu
		Vert = (Vert - Bleu) / a
		Rouge = (Rouge - Bleu) / a
		Bleu = 0
	ElseIf Vert < Bleu And Vert < Rouge
		a = 1 -(Vert / 255)
		Nuance_Blanc = 255 - Vert
		Bleu = (Bleu - Vert) / a
		Rouge = (Rouge - Vert) / a
		Vert = 0
	ElseIf Rouge < Bleu And Rouge < Vert
		a = 1 -(Rouge / 255)
		Nuance_Blanc = 255 - Rouge
		Bleu = (Bleu - Rouge) / a
		Vert = (Vert - Rouge) / a
		Rouge = 0
	ElseIf (Rouge > 0 And Bleu = 0 And Vert = 0) Or (Rouge = 0 And Bleu > 0 And Vert = 0) Or (Rouge = 0 And Bleu = 0 And Vert > 0)
		Nuance_Blanc = 255
	Else
		Nuance_Blanc = 0
	EndIf
	
	If Luminosity < 0
		Nuance_Noir - (255 - Nuance_Noir) * Luminosity
	ElseIf Nuance_Noir <> 0 Or Nuance_Blanc <> 0
		Level = Nuance_Noir /(Nuance_Noir + Nuance_Blanc)
		If Luminosity < Level
			Nuance_Noir *(1 - Luminosity / Level)
		Else
			Nuance_Noir = 0
			Nuance_Blanc *(1 - (Luminosity - Level) /(1 - Level))
		EndIf
	EndIf
	
	a = 1 - Nuance_Blanc / 255
	b = (255 - Nuance_Noir) / 255
	Rouge = (Rouge +(255 - Rouge) * a) * b
	If Rouge < 0
		Rouge = 0
	ElseIf Rouge > 255
		Rouge = 255
	EndIf
	Vert = (Vert +(255 - Vert) * a) * b
	If Vert < 0
		Vert = 0
	ElseIf Vert > 255
		Vert = 255
	EndIf
	Bleu = (Bleu +(255 - Bleu) * a) * b
	If Bleu < 0
		Bleu = 0
	ElseIf Bleu > 255
		Bleu = 255
	EndIf
	
	ProcedureReturn(Rouge | Vert << 8 | Bleu << 16 | Alpha << 24)
EndProcedure

CompilerIf #PB_Compiler_Debugger
	#NbIterationTestVitesse = 40000
CompilerElse
	#NbIterationTestVitesse = 4000000
CompilerEndIf

; Création de la fenêtre et de la GadgetList
If OpenWindow(0, 0, 0, 501, 320, "ColorLuminosity", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget) = 0
	End
EndIf

CreateImage(0, 501, 300, 32 | #PB_Image_Transparent)

StartDrawing(ImageOutput(0))
	DrawingMode(#PB_2DDrawing_AlphaBlend)
	
	Line(250, 0, 1, 300, $FF000000)
	
	For i = 0 To 500
		
		Teinte.f = (i - 250) / 250
		
		y = 10
		
		Couleur = $FF00C000
		Couleur2 = ColorLuminosity2(Couleur, Teinte)
		Line(i, y, 1, 20, Couleur2)
		y + 30
		
		Couleur = $FF0000FF
		Couleur2 = ColorLuminosity2(Couleur, Teinte)
		Line(i, y, 1, 20, Couleur2)
		y + 30
		
		Couleur = $FFAF0000
		Couleur2 = ColorLuminosity2(Couleur, Teinte)
		Line(i, y, 1, 20, Couleur2)
		y + 30
		
		Couleur = $FFC0A137
		Couleur2 = ColorLuminosity2(Couleur, Teinte)
		Line(i, y, 1, 20, Couleur2)
		y + 30
		
		Couleur = $FFD6FFAD
		Couleur2 = ColorLuminosity2(Couleur, Teinte)
		Line(i, y, 1, 20, Couleur2)
		y + 30
		
		Couleur = $FFFFFDEC
		Couleur2 = ColorLuminosity2(Couleur, Teinte)
		Line(i, y, 1, 20, Couleur2)
		y + 30
		
		Couleur = $FFFFFFFF
		Couleur2 = ColorLuminosity2(Couleur, Teinte)
		Line(i, y, 1, 20, Couleur2)
		y + 30
		
		Couleur = $FF163205
		Couleur2 = ColorLuminosity2(Couleur, Teinte)
		Line(i, y, 1, 20, Couleur2)
		y + 30
		
		Couleur = $FF000000
		Couleur2 = ColorLuminosity2(Couleur, Teinte)
		Line(i, y, 1, 20, Couleur2)
		y + 30
		
		Couleur = $FF808080
		Couleur2 = ColorLuminosity2(Couleur, Teinte)
		Line(i, y, 1, 20, Couleur2)
		y + 30
		
	Next
	
	Couleur = $FFC0A137
	Temps = ElapsedMilliseconds()
	For i = 1 To #NbIterationTestVitesse
		Couleur2 = ColorLuminosity2(Couleur, -0.5)
		Couleur2 = ColorLuminosity2(Couleur, 0.2)
		Couleur2 = ColorLuminosity2(Couleur, 0.8)
	Next
	Temps = ElapsedMilliseconds() - Temps
	
StopDrawing()


ImageGadget(0, 0, 0, 501, 300, ImageID(0))
TextGadget(1, 0, 300, 501, 20, "Temps de calcul = " + StrD(Temps * 1000 / #NbIterationTestVitesse / 3, 2) + "µs")

Repeat
	Event = WaitWindowEvent()
	
	Select Event
		Case #PB_Event_Menu
			Select EventMenu() ; Menus
					
			EndSelect
			
		Case #PB_Event_Gadget
			Select EventGadget() ; Gadgets
					
			EndSelect
	EndSelect
	
Until Event = #PB_Event_CloseWindow

Toute proposition d’optimisation est la bienvenue :D
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Re: Changer la luminosité d'une couleur

Message par Le Soldat Inconnu »

J'ai corrigé le code plus, il y avait un problème avec les couleurs en nuance de gris et le noir.

Sinon, j'ai codé une autre solution plus rapide mais le résultat est légèrement différent.
C'est surtout visible sur le vert foncé (avant avant dernière couleur)

Le premier code va arriver à donner de l'éclat au couleur
Le second donne une couleur qui reste moins vive.

Quelle solution préférez vous ?

Code : Tout sélectionner

; Auteur : Le Soldat Inconnu
; Version de PB : 4.50
;
; Explication du programme :
; Changer la satuation d'une couleur

Procedure ColorLuminosity2(Color, Luminosity.d) ; Change color luminisoty ( -1 <= Luminosity <= 1, Luminosity = -1 give black color, Luminosity = 1 give white color)
	Protected Rouge, Vert, Bleu, Gris, Alpha
	
	#Luminosity = 1
	
	If Luminosity > 1
		Luminosity = 1
	ElseIf Luminosity < -1
		Luminosity = -1
	EndIf
	
	Rouge = Color & $FF
	Vert = Color >> 8 & $FF
	Bleu = Color >> 16 & $FF
	Alpha = Color >> 24
	
	If Luminosity <= 0
		CompilerIf #Luminosity = 1
			Luminosity = 1 + Luminosity
		CompilerElse
			Luminosity = Pow(1 + Luminosity, 1 / #Luminosity)
		CompilerEndIf
		Rouge * Luminosity
		Vert * Luminosity
		Bleu * Luminosity
	Else
		CompilerIf #Luminosity <> 1
			Luminosity = Pow(Luminosity, #Luminosity)
		CompilerEndIf
		Rouge + (255 - Rouge) * Luminosity
		Vert + (255 - Vert) * Luminosity
		Bleu + (255 - Bleu) * Luminosity
	EndIf
	If Rouge > 255
		Rouge = 255
	ElseIf Rouge < 0
		Rouge = 0
	EndIf
	If Vert > 255
		Vert = 255
	ElseIf Vert < 0
		Vert = 0
	EndIf
	If Bleu > 255
		Bleu = 255
	ElseIf Bleu < 0
		Bleu = 0
	EndIf
	
	ProcedureReturn(Rouge | Vert << 8 | Bleu << 16 | Alpha << 24)
EndProcedure

CompilerIf #PB_Compiler_Debugger
	#NbIterationTestVitesse = 10000
CompilerElse
	#NbIterationTestVitesse = 1000000
CompilerEndIf

; Création de la fenêtre et de la GadgetList
If OpenWindow(0, 0, 0, 501, 320, "ColorLuminosity", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget) = 0
	End
EndIf

CreateImage(0, 501, 300, 32 | #PB_Image_Transparent)

StartDrawing(ImageOutput(0))
	DrawingMode(#PB_2DDrawing_AlphaBlend)
	
	Line(250, 0, 1, 300, $FF000000)
	
	For i = 0 To 500
		
		Teinte.f = (i - 250) / 250
		
		y = 10
		
		Couleur = $FF00C000
		Couleur2 = ColorLuminosity2(Couleur, Teinte)
		Line(i, y, 1, 20, Couleur2)
		y + 30
		
		Couleur = $FF0000FF
		Couleur2 = ColorLuminosity2(Couleur, Teinte)
		Line(i, y, 1, 20, Couleur2)
		y + 30
		
		Couleur = $FFAF0000
		Couleur2 = ColorLuminosity2(Couleur, Teinte)
		Line(i, y, 1, 20, Couleur2)
		y + 30
		
		Couleur = $FFC0A137
		Couleur2 = ColorLuminosity2(Couleur, Teinte)
		Line(i, y, 1, 20, Couleur2)
		y + 30
		
		Couleur = $FFD6FFAD
		Couleur2 = ColorLuminosity2(Couleur, Teinte)
		Line(i, y, 1, 20, Couleur2)
		y + 30
		
		Couleur = $FFFFFDEC
		Couleur2 = ColorLuminosity2(Couleur, Teinte)
		Line(i, y, 1, 20, Couleur2)
		y + 30
		
		Couleur = $FFFFFFFF
		Couleur2 = ColorLuminosity2(Couleur, Teinte)
		Line(i, y, 1, 20, Couleur2)
		y + 30
		
		Couleur = $FF163205
		Couleur2 = ColorLuminosity2(Couleur, Teinte)
		Line(i, y, 1, 20, Couleur2)
		y + 30
		
		Couleur = $FF000000
		Couleur2 = ColorLuminosity2(Couleur, Teinte)
		Line(i, y, 1, 20, Couleur2)
		y + 30
		
		Couleur = $FF808080
		Couleur2 = ColorLuminosity2(Couleur, Teinte)
		Line(i, y, 1, 20, Couleur2)
		y + 30
		
	Next
	
	Couleur = $FFC0A137
	Temps = ElapsedMilliseconds()
	For i = 1 To #NbIterationTestVitesse
		Couleur2 = ColorLuminosity2(Couleur, -0.5)
		Couleur2 = ColorLuminosity2(Couleur, 0.2)
		Couleur2 = ColorLuminosity2(Couleur, 0.8)
	Next
	Temps = ElapsedMilliseconds() - Temps
	
StopDrawing()


ImageGadget(0, 0, 0, 501, 300, ImageID(0))
TextGadget(1, 0, 300, 501, 20, "Temps de calcul = " + StrD(Temps * 1000 / #NbIterationTestVitesse / 3, 2) + "µs")

Repeat
	Event = WaitWindowEvent()
	
	Select Event
		Case #PB_Event_Menu
			Select EventMenu() ; Menus
					
			EndSelect
			
		Case #PB_Event_Gadget
			Select EventGadget() ; Gadgets
					
			EndSelect
	EndSelect
	
Until Event = #PB_Event_CloseWindow
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Avatar de l’utilisateur
Jacobus
Messages : 1559
Inscription : mar. 06/avr./2004 10:35
Contact :

Re: Changer la luminosité d'une couleur

Message par Jacobus »

Bin les deux tiens :lol:
Une que tu peux nommer Lumière brillante et l'autre Lumière Mate, ou quelque chose dans le genre... m'enfin c'est toi qui voit.
Quand tous les glands seront tombés, les feuilles dispersées, la vigueur retombée... Dans la morne solitude, ancré au coeur de ses racines, c'est de sa force maturité qu'il renaîtra en pleine magnificence...Jacobus.
PAPIPP
Messages : 534
Inscription : sam. 23/févr./2008 17:58

Re: Changer la luminosité d'une couleur

Message par PAPIPP »

Bonjour à tous

Voici ma petite contribution à partir du prg de LSI

les 6 premières bandes représentent les couleurs saturées
-1)La verte de la saturation au blanc
-2)la verte du noir à la couleur saturée
-3)la rouge de la saturation au blanc
-4)la rouge du noir à la couleur saturée
-5)la bleue de la saturation au blanc
-6)la bleue du noir à la couleur saturée

ensuite 3 bandes qui vont du noir au blanc en passant par
-7) Rouge saturé
-8) vert saturé
-9) bleu saturé

Enfin 3 bandes Jaune et Cyan et Magenta qui vont du noir au blanc en passant par le jaune , Cyan et magenta


Code : Tout sélectionner

 ; Création de la fenêtre et de la GadgetList
If OpenWindow(0,0,0,507,380,"ColorLuminosity",#PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget)=0
  End
EndIf
;   Temps=ElapsedMilliseconds()

CreateImage(0,506,360,32 | #PB_Image_Transparent)

StartDrawing(ImageOutput(0))
  DrawingMode(#PB_2DDrawing_AlphaBlend)
  
  Line(250,0,1,300,$FF000000)
  
  For i=0 To 511 ;255*2
    
    ;     Teinte.f=(i-250)/250
    teinte.w=i/2
    y=10
    ; COULEUR VERTE
    couleur2=RGBA(teinte,255,teinte,255)
    ;     Debug couleur2
    Line(i,y,1,20,Couleur2)
    y+30
    couleur2=RGBA(0,teinte,0,255)
    Line(i,y,1,20,Couleur2)
    y+30
    ; COULEUR ROUGE
    couleur2=RGBA(255,teinte,teinte,255)
    Line(i,y,1,20,Couleur2)
    y+30
    
    couleur2=RGBA(teinte,0,0,255)
    Line(i,y,1,20,Couleur2)
    y+30
    ; COULEUR BLEU
    couleur2=RGBA(teinte,teinte,255,255)
    Line(i,y,1,20,Couleur2)
    y+30
    
    couleur2=RGBA(0,0,teinte,255)
    Line(i,y,1,20,Couleur2)
    y+30
    
    ;COULEUR ROUGE DEGRADE COMPLET
    If i<256
      couleur2=RGBA(i,0,0,255)
    Else
      ii=i-256
      couleur2=RGBA(255,ii,ii,255)
    EndIf
    Line(i,y,1,20,Couleur2)
    y+30
    ;COULEUR VERTE DEGRADE COMPLET
    If i<256
      couleur2=RGBA(0,i,0,255)
    Else
      ii=i-256
      couleur2=RGBA(ii,255,ii,255)
    EndIf
    Line(i,y,1,20,Couleur2)
    y+30
    ;COULEUR BLEU DEGRADE COMPLET
    If i<256
      couleur2=RGBA(0,0,i,255)
    Else
      ii=i-256
      couleur2=RGBA(ii,ii,255,255)
    EndIf
    Line(i,y,1,20,Couleur2)
    y+30
    ;COULEUR JAUNE DEGRADE COMPLET
    
    If i<256
        couleur2=RGBA(i,i,0,255)
    Else
      ii=i-256
      couleur2=RGBA(255,255,ii,255)
    EndIf
    Line(i,y,1,20,Couleur2)
    y+30
    
      ;COULEUR CYAN DEGRADE COMPLET
    
    If i<256
        couleur2=RGBA(0,i,i,255)
    Else
      ii=i-256
      couleur2=RGBA(ii,255,255,255)
    EndIf
    Line(i,y,1,20,Couleur2)
    y+30
        ;COULEUR MAGENTA DEGRADE COMPLET
    
    If i<256
        couleur2=RGBA(i,0,i,255)
    Else
      ii=i-256
      couleur2=RGBA(255,ii,255,255)
    EndIf
    Line(i,y,1,20,Couleur2)
    y+30

  Next
  

StopDrawing()

;   Temps=ElapsedMilliseconds()-Temps
;   Debug temps

ImageGadget(0,0,0,501,300,ImageID(0))
; TextGadget(1,0,300,501,20,"Temps de calcul = "+Str(Temps)+"ms")

Repeat
  Event=WaitWindowEvent()
  
  Select Event
    Case #PB_Event_Menu
      Select EventMenu() ; Menus
          
      EndSelect
      
    Case #PB_Event_Gadget
      Select EventGadget() ; Gadgets
          
      EndSelect
  EndSelect
  
Until Event=#PB_Event_CloseWindow

Il est fort peu probable que les mêmes causes ne produisent pas les mêmes effets.(Einstein)
Et en logique positive cela donne.
Il est très fortement probable que les mêmes causes produisent les mêmes effets.
Répondre