Page 1 sur 1

Modifier les couleurs d'une image

Publié : sam. 19/oct./2013 19:14
par blendman
salut

Pour modifier les couleurs d'une image , par exemple avec 3 TrackBarGadget() pour les canaux R, G et B.

j'utilise la méthode suivante :

Code : Tout sélectionner

 b = PeekA(Buffer + 4 * i + j * lineLength);Bleu
                g = PeekA(Buffer + 4 * i + j * lineLength + 1);Vert
                r = PeekA(Buffer + 4 * i + j * lineLength + 2);Rouge 
                
                ; on effectue l'opération         
                r = r + r1
                If r > 255
                  r = 255
                EndIf
                
                g = g + g1
                If g > 255
                  g = 255
                EndIf
                
                b = b + b1
                If b > 255
                  b =255
                EndIf
                
                ; on poke le pixel
                PokeA(Buffer + 4 * i + j * lineLength,      b);Bleu
                PokeA(Buffer + 4 * i + j * lineLength + 1,  g);Vert
                PokeA(Buffer + 4 * i + j * lineLength + 2,  r);Rouge  
                
ça fonctionne. Mais j'aimerais éviter d'ajouter de la luminosité dans l'image.

savez-vous comment je peux corriger ce code pour améliorer ça ?

Re: Modifier les couleurs d'une image

Publié : sam. 19/oct./2013 20:19
par SPH
La question est : peut on ajouter du R du G et du B sans augmenter la luminosité d'une couleur ?
Je pense que la reponse est non :|

Re: Modifier les couleurs d'une image

Publié : sam. 19/oct./2013 20:45
par Backup
++

Re: Modifier les couleurs d'une image

Publié : sam. 19/oct./2013 23:29
par Ar-S
Un peu HS mais tant qu'on y est pour l'effet négatif il faut soustraire les valeurs RGB à 255

Code : Tout sélectionner

R = 255-R
G = 255-G
B = 255-B

Re: Modifier les couleurs d'une image

Publié : dim. 20/oct./2013 7:50
par Micoute
Bonjours à tous, pour ma part, j'ai ça, c'est du code que j'ai pompé à droite et à gauche, la plupart vient de LSI entre autre

Code : Tout sélectionner

ProcedureDLL Teinte(Couleur.i) ; Donne la teinte d'une couleur (Hue)
	Protected fTeinte.f, Rouge.i, Vert.i, Bleu.i, Minimum.i, Maximum.i, Difference.i
	Rouge = Red(Couleur) : Vert = Green(Couleur) : Bleu = Blue(Couleur)
	If Rouge =  Vert And Rouge = Bleu And Vert = Bleu
		ProcedureReturn 160
	EndIf
	If Rouge < Vert And Rouge < Bleu
		Minimum = Rouge
		If Vert > Bleu
			Maximum = Vert
		Else
			Maximum = Bleu
		EndIf
	ElseIf Vert < Bleu
		Minimum = Vert
		If Rouge > Bleu
			Maximum = Rouge
		Else
			Maximum = Bleu
		EndIf
	Else
		Minimum = Bleu
		If Rouge > Vert
			Maximum = Rouge
		Else
			Maximum = Vert
		EndIf
	EndIf
	Difference = Maximum-Minimum
	If Rouge = Maximum
		fTeinte = (Vert-Bleu)/Difference
	ElseIf Vert = Maximum
		fTeinte = (Bleu-Rouge)/Difference + 2
	Else
		fTeinte = (Rouge-Vert)/Difference + 4
	EndIf
	If fTeinte< 0
		ProcedureReturn 240+Round(Mod((1/6*(fTeinte*240)), 240), #PB_Round_Nearest)
	Else
		ProcedureReturn Round(Mod((1/6*(fTeinte*240)), 240), #PB_Round_Nearest)
	EndIf
	
EndProcedure

ProcedureDLL Luminosite(Couleur.i) ; Donne la luminosité d'une couleur
	Protected Rouge.i, Vert.i, Bleu.i, Minimum.i, Maximum.i
	Rouge = Red(Couleur) : Vert = Green(Couleur) : Bleu = Blue(Couleur)
	If Rouge < Vert And Rouge < Bleu
		Minimum = Rouge
		If Vert > Bleu
			Maximum = Vert
		Else
			Maximum = Bleu
		EndIf
	ElseIf Vert < Bleu
		Minimum = Vert
		If Rouge > Bleu
			Maximum = Rouge
		Else
			Maximum = Bleu
		EndIf
	Else
		Minimum = Bleu
		If Rouge > Vert
			Maximum = Rouge
		Else
			Maximum = Vert
		EndIf
	EndIf
	ProcedureReturn Round((240*(Maximum + Minimum)/510), #PB_Round_Nearest)
EndProcedure

ProcedureDLL Saturation(Couleur.i) ; retourne la saturation d'une couleur
	Protected Rouge.i, Vert.i, Bleu.i, Minimum.i, Maximum.i
	Rouge = Red(Couleur) : Vert = Green(Couleur) : Bleu = Blue(Couleur)
	If (Rouge = 0 And Vert = 0 And Bleu = 0) Or (Rouge = 255 And Vert = 255 And Bleu = 255)
		ProcedureReturn 0
	EndIf
	If Rouge < Vert And Rouge < Bleu
		Minimum = Rouge
		If Vert > Bleu
			Maximum = Vert
		Else
			Maximum = Bleu
		EndIf
	ElseIf Vert < Bleu
		Minimum = Vert
		If Rouge > Bleu
			Maximum = Rouge
		Else
			Maximum = Bleu
		EndIf
	Else
		Minimum = Bleu
		If Rouge > Vert
			Maximum = Rouge
		Else
			Maximum = Vert
		EndIf
	EndIf
	If Maximum+Minimum =< 255
		ProcedureReturn Round(((Maximum-Minimum)/(Maximum+Minimum)*240),#PB_Round_Nearest)
	Else
		ProcedureReturn Round(((Maximum-Minimum)/(510-(Maximum+Minimum))*240), #PB_Round_Nearest)
	EndIf
EndProcedure

ProcedureDLL.i Lumiere(Couleur.i, Echelle.f) ; Eclaicir ou foncer une couleur
	Protected Rouge.i, Vert.i, Bleu.i, Alpha.i
	
	Rouge = Couleur & $FF
	Vert = Couleur >> 8 & $FF
	Bleu = Couleur >> 16 & $FF
	Alpha = Couleur >> 24
	Rouge * Echelle
	Vert * Echelle
	Bleu * Echelle
	
	If Rouge > 255 : Rouge = 255 : EndIf
	If Vert > 255 : Vert = 255 : EndIf
	If Bleu > 255 : Bleu = 255 : EndIf
	
	ProcedureReturn (Rouge | Vert <<8 | Bleu << 16 | Alpha << 24)
EndProcedure

ProcedureDLL.i Contraste(Couleur.i, Echelle.f) ; Constrater la couleur, échelle négative pour diminuer et positive pour augmenter.
	Protected Rouge.i, Vert.i, Bleu.i, Alpha.i
	
	Rouge = Couleur & $FF
	Vert = Couleur >> 8 & $FF
	Bleu = Couleur >> 16 & $FF
	Alpha = Couleur >> 24
	Rouge * Echelle + 127 * (1 - Echelle)
	Vert * Echelle + 127 * (1 - Echelle)
	Bleu * Echelle + 127 * (1 - Echelle)
	
	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

ProcedureDLL.i Gris(Couleur.i) ; Rendre la couleur en nuance de gris
	Protected Rouge.i, Vert.i, Bleu.i, Alpha.i
	
	Rouge = Couleur & $FF
	Vert = Couleur >> 8 & $FF
	Bleu = Couleur >> 16 & $FF
	Alpha = Couleur >> 24
	Couleur = (Rouge + Vert + Bleu) * 0.33333333
	ProcedureReturn (Couleur | Couleur <<8 | Couleur << 16 | Alpha << 24)
EndProcedure

ProcedureDLL.i CouleurNegative(Couleur.i) ; Renvoi la couleur en négatif
	Protected Rouge.i, Vert.i, Bleu.i, Alpha.i
	Rouge = 255 - Couleur & $FF
	Vert = 255 - Couleur >> 8 & $FF
	Bleu = 255 - Couleur >> 16 & $FF
	Alpha = Couleur >> 24
	ProcedureReturn (Rouge | Vert <<8 | Bleu << 16 | Alpha << 24)
EndProcedure

ProcedureDLL.i IntensiteRouge(Couleur.i, Echelle.f) ; Eclaicir ou foncer la composante rouge d'une couleur
	Protected Rouge.i
	
	Rouge = Couleur & $FF
	Rouge * Echelle
	
	If Rouge > 255 : Rouge = 255 : EndIf
	
	ProcedureReturn (Couleur & $FFFFFF00 | Rouge)
EndProcedure

ProcedureDLL.i IntensiteVert(Couleur.i, Echelle.f) ; Eclaicir ou foncer la composante verte d'une couleur
	Protected Vert.i
	
	Vert = Couleur >> 8 & $FF
	Vert * Echelle
	
	If Vert > 255 : Vert = 255 : EndIf
	
	ProcedureReturn (Couleur & $FFFF00FF | Vert << 8)
EndProcedure

ProcedureDLL.i IntensiteBleu(Couleur.i, Echelle.f) ; Eclaicir ou foncer la composante bleue d'une couleur
	Protected Bleu.i
	
	Bleu = Couleur >> 16 & $FF
	Bleu * Echelle
	
	If Bleu > 255 : Bleu = 255 : EndIf
	
	ProcedureReturn (Couleur & $FF00FFFF | Bleu << 16)
EndProcedure

ProcedureDLL.i IntensiteJaune(Couleur.i, Echelle.f) ; Eclaicir ou foncer la composante jaune d'une couleur
	Protected Rouge.i, Vert.i
	
	Rouge = Couleur & $FF
	Vert = Couleur >> 8 & $FF
	Rouge * Echelle
	Vert * Echelle
	
	If Rouge > 255 : Rouge = 255 : EndIf
	If Vert > 255 : Vert = 255 : EndIf
	
	ProcedureReturn (Couleur & $FFFF0000 | Rouge | Vert << 8)
EndProcedure

ProcedureDLL.i IntensiteCyan(Couleur.i, Echelle.f) ; Eclaicir ou foncer la composante cyan d'une couleur
	Protected Vert.i, Bleu.i
	
	Vert = Couleur >> 8 & $FF
	Bleu = Couleur >> 16 & $FF
	Vert * Echelle
	Bleu * Echelle
	
	If Vert > 255 : Vert = 255 : EndIf
	If Bleu > 255 : Bleu = 255 : EndIf
	
	ProcedureReturn (Couleur & $FF0000FF | Vert << 8 | Bleu << 16)
EndProcedure

ProcedureDLL.i IntensiteViolet(Couleur.i, Echelle.f) ; Eclaicir ou foncer la composante violet d'une couleur
	Protected Rouge.i, Bleu.i
	
	Rouge = Couleur & $FF
	Bleu = Couleur >> 16 & $FF
	Rouge * Echelle
	Bleu * Echelle
	
	If Rouge > 255 : Rouge = 255 : EndIf
	If Bleu > 255 : Bleu = 255 : EndIf
	
	ProcedureReturn (Couleur & $FF00FF00 | Rouge | Bleu << 16)
EndProcedure

ProcedureDLL Teinter(Couleur.i, Echelle.f) ; Changer la teinte d'une couleur (Echelle comprise entre -1 et 1)
	Protected Rouge.i, Vert.i, Bleu.i, Alpha.i, a.f, Nuance_Blanc.i, Nuance_Noir.i, B.f, i.i, ii.i
	
	Rouge = Couleur & $FF
	Vert = Couleur >> 8 & $FF
	Bleu = Couleur >> 16 & $FF
	Alpha = Couleur >> 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 = Bleu / 255
		Nuance_Blanc = 255 - Bleu
		Vert = (Vert - Bleu) / (1 - a)
		Rouge = (Rouge - Bleu) / (1 - a)
		Bleu = 0
	ElseIf Vert < Bleu And Vert < Rouge
		a = Vert / 255
		Nuance_Blanc = 255 - Vert
		Bleu = (Bleu - Vert) / (1 - a)
		Rouge = (Rouge - Vert) / (1 - a)
		Vert = 0
	ElseIf Rouge < Bleu And Rouge < Vert
		a = Rouge / 255
		Nuance_Blanc = 255 - Rouge
		Bleu = (Bleu - Rouge) / (1 - a)
		Vert = (Vert - Rouge) / (1 - a)
		Rouge = 0
	Else
		Nuance_Blanc = 255
	EndIf
	
	ii = Echelle * 1530
	If ii > 0
		For i = 1 To ii
			If Rouge = 255 And Vert <> 255 And Bleu = 0
				Vert + 1
			ElseIf Vert = 255 And Rouge <> 0 And Bleu = 0
				Rouge - 1
			ElseIf Vert = 255 And Bleu <> 255 And Rouge = 0
				Bleu + 1
			ElseIf Bleu = 255 And Vert <> 0 And Rouge = 0
				Vert - 1
			ElseIf Bleu = 255 And Rouge <> 255 And Vert = 0
				Rouge + 1
			ElseIf Rouge = 255 And Bleu <> 0 And Vert = 0
				Bleu - 1
			EndIf
		Next
	Else
		ii = -ii
		For i = 1 To ii
			If Bleu = 255 And Vert <> 255 And Rouge = 0
				Vert + 1
			ElseIf Vert = 255 And Bleu <> 0 And Rouge = 0
				Bleu - 1
			ElseIf Vert = 255 And Rouge <> 255 And Bleu = 0
				Rouge + 1
			ElseIf Rouge = 255 And Vert <> 0 And Bleu = 0
				Vert - 1
			ElseIf Rouge = 255 And Bleu <> 255 And Vert = 0
				Bleu + 1
			ElseIf Bleu = 255 And Rouge <> 0 And Vert = 0
				Rouge - 1
			EndIf
		Next
	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

ProcedureDLL.i Niveau(Couleur.i, Minimum.i, Maximum.i) ; Changer les niveaux de blanc et de noir de la couleur
	Protected Rouge.i, Vert.i, Bleu.i, Alpha.i, a.f, b.f
	
	a = 255 / (Maximum - Minimum)
	b = -a * Minimum
	
	Rouge = Couleur & $FF
	Vert = Couleur >> 8 & $FF
	Bleu = Couleur >> 16 & $FF
	Alpha = Couleur >> 24
	Rouge * a + b
	Vert * a + b
	Bleu * a + b
	
	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

ProcedureDLL.i Melanger(Couleur1.i, Couleur2.i, Echelle.f) ; Mélanger 2 couleurs
	Protected Rouge.i, Vert.i, Bleu.i, Alpha.i, Rouge2.i, Vert2.i, Bleu2.i
	
	Rouge = Couleur1 & $FF
	Vert = Couleur1 >> 8 & $FF
	Bleu = Couleur1 >> 16 & $FF
	Alpha = Couleur1 >> 24
	Rouge2 = Couleur2 & $FF
	Vert2 = Couleur2 >> 8 & $FF
	Bleu2 = Couleur2 >> 16 & $FF
	
	Rouge = Rouge * Echelle + Rouge2 * (1-Echelle)
	Vert = Vert * Echelle + Vert2 * (1-Echelle)
	Bleu = Bleu * Echelle + Bleu2 * (1-Echelle)
	
	ProcedureReturn (Rouge | Vert <<8 | Bleu << 16 | Alpha << 24)
EndProcedure

ProcedureDLL.i Ajouter(Couleur1.i, Couleur2.i) ; Ajouter 2 couleurs
	Protected Rouge.i, Vert.i, Bleu.i, Alpha.i
	
	Rouge = Couleur1 & $FF + Couleur2 & $FF
	Vert = Couleur1 >> 8 & $FF + Couleur2 >> 8 & $FF
	Bleu = Couleur1 >> 16 & $FF + Couleur2 >> 16 & $FF
	Alpha = Couleur1 >> 24
	
	If Rouge > 255 : Rouge = 255 : EndIf
	If Vert > 255 : Vert = 255 : EndIf
	If Bleu > 255 : Bleu = 255 : EndIf
	
	ProcedureReturn (Rouge | Vert <<8 | Bleu << 16 | Alpha << 24)
EndProcedure

ProcedureDLL.i Ajouter2(Couleur1.i, Couleur2.i, Echelle.f) ; Ajouter 2 couleurs
	Protected Rouge.i, Vert.i, Bleu.i, Alpha.i, Rouge2.i, Vert2.i, Bleu2.i
	
	Rouge = Couleur1 & $FF
	Vert = Couleur1 >> 8 & $FF
	Bleu = Couleur1 >> 16 & $FF
	Alpha = Couleur1 >> 24
	Rouge2 = Couleur2 & $FF
	Vert2 = Couleur2 >> 8 & $FF
	Bleu2 = Couleur2 >> 16 & $FF
	
	Rouge + Rouge2 * Echelle
	Vert + Vert2 * Echelle
	Bleu + Bleu2 * Echelle
	
	If Rouge > 255 : Rouge = 255 : EndIf
	If Vert > 255 : Vert = 255 : EndIf
	If Bleu > 255 : Bleu = 255 : EndIf
	
	ProcedureReturn (Rouge | Vert <<8 | Bleu << 16 | Alpha << 24)
EndProcedure

ProcedureDLL.i Colorier(Couleur.i, CouleurFinale.i) ; Colorier une couleur avec une autre Couleur
	Protected Rouge.i, Vert.i, Bleu.i, Alpha.i, a.f, Nuance_Blanc.i, Nuance_Noir.i, b.f
	
	Rouge = Couleur & $FF
	Vert = Couleur >> 8 & $FF
	Bleu = Couleur >> 16 & $FF
	Alpha = Couleur >> 24
	
	If Bleu >= Vert And Bleu >= Rouge And Bleu > 0
		Nuance_Noir = 255 - Bleu
	ElseIf Vert >= Bleu And Vert >= Rouge And Vert > 0
		Nuance_Noir = 255 - Vert
	ElseIf Rouge >= Vert And Rouge >= Bleu And Rouge > 0
		Nuance_Noir = 255 - Rouge
	Else
		Nuance_Noir = 255
	EndIf
	
	If Bleu < Vert And Bleu < Rouge
		Nuance_Blanc = 255 - Bleu
	ElseIf Vert < Bleu And Vert < Rouge
		Nuance_Blanc = 255 - Vert
	ElseIf Rouge < Bleu And Rouge < Vert
		Nuance_Blanc = 255 - Rouge
	Else
		Nuance_Blanc = 255
	EndIf
	
	Rouge = CouleurFinale & $FF
	Vert = CouleurFinale >> 8 & $FF
	Bleu = CouleurFinale >> 16
	
	If Bleu >= Vert And Bleu >= Rouge And Bleu > 0
		a = 255 / Bleu
		Bleu = 255
		Vert = a * Vert
		Rouge = a * Rouge
	ElseIf Vert >= Bleu And Vert >= Rouge And Vert > 0
		a = 255 / Vert
		Bleu = a * Bleu
		Vert = 255
		Rouge = a * Rouge
	ElseIf Rouge >= Vert And Rouge >= Bleu And Rouge > 0
		a = 255 / Rouge
		Bleu = a * Bleu
		Vert = a * Vert
		Rouge = 255
	EndIf
	
	If Bleu < Vert And Bleu < Rouge
		a = Bleu / 255
		Vert = (Vert - Bleu) / (1 - a)
		Rouge = (Rouge - Bleu) / (1 - a)
		Bleu = 0
	ElseIf Vert < Bleu And Vert < Rouge
		a = Vert / 255
		Bleu = (Bleu - Vert) / (1 - a)
		Rouge = (Rouge - Vert) / (1 - a)
		Vert = 0
	ElseIf Rouge < Bleu And Rouge < Vert
		a = Rouge / 255
		Bleu = (Bleu - Rouge) / (1 - a)
		Vert = (Vert - Rouge) / (1 - a)
		Rouge = 0
	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

ProcedureDLL.i Colorier2(Couleur.i, CouleurFinale.i, Intensite.f) ; Colorier une couleur avec une autre Couleur
	Protected Rouge.i, Vert.i, Bleu.i, Alpha.i, a.f, Nuance_Blanc.i, Nuance_Noir.i, b.f
	
	Rouge = Couleur & $FF
	Vert = Couleur >> 8 & $FF
	Bleu = Couleur >> 16 & $FF
	Alpha = Couleur >> 24
	
	If Bleu >= Vert And Bleu >= Rouge And Bleu > 0
		Nuance_Noir = 255 - Bleu
	ElseIf Vert >= Bleu And Vert >= Rouge And Vert > 0
		Nuance_Noir = 255 - Vert
	ElseIf Rouge >= Vert And Rouge >= Bleu And Rouge > 0
		Nuance_Noir = 255 - Rouge
	Else
		Nuance_Noir = 255
	EndIf
	
	If Bleu < Vert And Bleu < Rouge
		Nuance_Blanc = 255 - Bleu
	ElseIf Vert < Bleu And Vert < Rouge
		Nuance_Blanc = 255 - Vert
	ElseIf Rouge < Bleu And Rouge < Vert
		Nuance_Blanc = 255 - Rouge
	Else
		Nuance_Blanc = 255
	EndIf
	
	Rouge = CouleurFinale & $FF
	Vert = CouleurFinale >> 8 & $FF
	Bleu = CouleurFinale >> 16
	
	If Bleu >= Vert And Bleu >= Rouge And Bleu > 0
		a = 255 / Bleu
		Bleu = 255
		Vert = a * Vert
		Rouge = a * Rouge
	ElseIf Vert >= Bleu And Vert >= Rouge And Vert > 0
		a = 255 / Vert
		Bleu = a * Bleu
		Vert = 255
		Rouge = a * Rouge
	ElseIf Rouge >= Vert And Rouge >= Bleu And Rouge > 0
		a = 255 / Rouge
		Bleu = a * Bleu
		Vert = a * Vert
		Rouge = 255
	EndIf
	
	If Bleu < Vert And Bleu < Rouge
		a = Bleu / 255
		Vert = (Vert - Bleu) / (1 - a)
		Rouge = (Rouge - Bleu) / (1 - a)
		Bleu = 0
	ElseIf Vert < Bleu And Vert < Rouge
		a = Vert / 255
		Bleu = (Bleu - Vert) / (1 - a)
		Rouge = (Rouge - Vert) / (1 - a)
		Vert = 0
	ElseIf Rouge < Bleu And Rouge < Vert
		a = Rouge / 255
		Bleu = (Bleu - Rouge) / (1 - a)
		Vert = (Vert - Rouge) / (1 - a)
		Rouge = 0
	EndIf  
	
	a = 1 - Nuance_Blanc / 255 * Intensite
	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

ProcedureDLL.i Substituer(Couleur.i, CouleurFinale.i) ; Changer une nuance de couleur par une autre
	Protected Rouge.i, Vert.i, Bleu.i, Alpha.i, a.f, Nuance_Blanc.i, Nuance_Noir.i, b.f
	
	Rouge = Couleur & $FF
	Vert = Couleur >> 8 & $FF
	Bleu = Couleur >> 16 & $FF
	Alpha = Couleur >> 24
	
	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
		Nuance_Blanc = 255 - Bleu
	ElseIf Vert < Bleu And Vert < Rouge
		Nuance_Blanc = 255 - Vert
	ElseIf Rouge < Bleu And Rouge < Vert
		Nuance_Blanc = 255 - Rouge
	Else
		Nuance_Blanc = 255
	EndIf
	
	Rouge = CouleurFinale & $FF
	Vert = CouleurFinale >> 8 & $FF
	Bleu = CouleurFinale >> 16
	
	If Bleu >= Vert And Bleu >= Rouge And Bleu > 0
		a = 255 / Bleu
		Bleu = 255
		Vert = a * Vert
		Rouge = a * Rouge
	ElseIf Vert >= Bleu And Vert >= Rouge And Vert > 0
		a = 255 / Vert
		Bleu = a * Bleu
		Vert = 255
		Rouge = a * Rouge
	ElseIf Rouge >= Vert And Rouge >= Bleu And Rouge > 0
		a = 255 / Rouge
		Bleu = a * Bleu
		Vert = a * Vert
		Rouge = 255
	EndIf
	
	If Bleu < Vert And Bleu < Rouge
		a = Bleu / 255
		Vert = (Vert - Bleu) / (1 - a)
		Rouge = (Rouge - Bleu) / (1 - a)
		Bleu = 0
	ElseIf Vert < Bleu And Vert < Rouge
		a = Vert / 255
		Bleu = (Bleu - Vert) / (1 - a)
		Rouge = (Rouge - Vert) / (1 - a)
		Vert = 0
	ElseIf Rouge < Bleu And Rouge < Vert
		a = Rouge / 255
		Bleu = (Bleu - Rouge) / (1 - a)
		Vert = (Vert - Rouge) / (1 - a)
		Rouge = 0
	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

ProcedureDLL.i Substituer2(Couleur.i, CouleurFinale.i, Intensite.f) ; Changer une nuance de couleur par une autre
	Protected Rouge.i, Vert.i, Bleu.i, Alpha.i, a.f, Nuance_Blanc.i, Nuance_Noir.i, b.f
	
	Rouge = Couleur & $FF
	Vert = Couleur >> 8 & $FF
	Bleu = Couleur >> 16 & $FF
	Alpha = Couleur >> 24
	
	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
		Nuance_Blanc = 255 - Bleu
	ElseIf Vert < Bleu And Vert < Rouge
		Nuance_Blanc = 255 - Vert
	ElseIf Rouge < Bleu And Rouge < Vert
		Nuance_Blanc = 255 - Rouge
	Else
		Nuance_Blanc = 255
	EndIf
	
	Rouge = CouleurFinale & $FF
	Vert = CouleurFinale >> 8 & $FF
	Bleu = CouleurFinale >> 16
	
	If Bleu >= Vert And Bleu >= Rouge And Bleu > 0
		a = 255 / Bleu
		Bleu = 255
		Vert = a * Vert
		Rouge = a * Rouge
	ElseIf Vert >= Bleu And Vert >= Rouge And Vert > 0
		a = 255 / Vert
		Bleu = a * Bleu
		Vert = 255
		Rouge = a * Rouge
	ElseIf Rouge >= Vert And Rouge >= Bleu And Rouge > 0
		a = 255 / Rouge
		Bleu = a * Bleu
		Vert = a * Vert
		Rouge = 255
	EndIf
	
	If Bleu < Vert And Bleu < Rouge
		a = Bleu / 255
		Vert = (Vert - Bleu) / (1 - a)
		Rouge = (Rouge - Bleu) / (1 - a)
		Bleu = 0
	ElseIf Vert < Bleu And Vert < Rouge
		a = Vert / 255
		Bleu = (Bleu - Vert) / (1 - a)
		Rouge = (Rouge - Vert) / (1 - a)
		Vert = 0
	ElseIf Rouge < Bleu And Rouge < Vert
		a = Rouge / 255
		Bleu = (Bleu - Rouge) / (1 - a)
		Vert = (Vert - Rouge) / (1 - a)
		Rouge = 0
	EndIf
	
	
	
	a = 1 - Nuance_Blanc / 255 * Intensite
	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

ProcedureDLL.i DefinirBitsImage(ImageID.i, HListe.i) ; Transfert d'un tableau vers une image
	Protected bmi.BITMAPINFO, hdc.i, Resultat.i, Mem.i, n.i, nn.i, bm.BITMAP, Temp1.i, Temp2.i, Temp3.i, Temp4.i, HList.i
	
	Resultat = 0
	
	GetObject_(ImageID, SizeOf(BITMAP), @bm.BITMAP)
	
	bmi\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
	bmi\bmiHeader\biWidth = bm\bmWidth
	bmi\bmiHeader\biHeight = bm\bmHeight
	bmi\bmiHeader\biPlanes = 1
	bmi\bmiHeader\biBitCount = 32
	If bm\bmBitsPixel = 24
		bmi\bmiHeader\biCompression = #BI_RGB
	EndIf
	
	Mem = AllocateMemory(bm\bmWidth * bm\bmHeight * 4)
	If Mem
		
		; On convertit la liste dans le bon format
		Temp1 = bm\bmHeight - 1
		Temp2 = bm\bmWidth - 1
		For nn = 0 To Temp2
			For n = 0 To Temp1
				Temp3 = Mem + (nn + (Temp1 - n) * bm\bmWidth) * 4
				PokeL(Temp3, PeekL(HList))
				PokeB(Temp3 + 2, PeekB(HList))
				PokeB(Temp3, PeekB(HList + 2))
				HList + 4
			Next
		Next
		
		hdc = CreateCompatibleDC_(GetDC_(ImageID))
		If hdc
			SetDIBits_(hdc, ImageID, 0, bm\bmHeight, Mem, @bmi, #DIB_RGB_COLORS) ; on envoie la liste dans l'image
			DeleteDC_(hdc)
			Resultat = ImageID
		EndIf
		
		FreeMemory(Mem)
	EndIf
	
	ProcedureReturn Resultat
EndProcedure

ProcedureDLL.i DonnerBitsImage(ImageID.i, HListe.i) ; Transfert d'une image vers un tableau
	Protected bmi.BITMAPINFO, hdc.i, Resultat.i, Mem.i, n.i, nn.i, bm.BITMAP, Temp1.i, Temp2.i, Temp3.i, Temp4.i, HList.i
	
	Resultat = 0
	
	GetObject_(ImageID, SizeOf(BITMAP), @bm.BITMAP)
	
	bmi\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
	bmi\bmiHeader\biWidth = bm\bmWidth
	bmi\bmiHeader\biHeight = bm\bmHeight
	bmi\bmiHeader\biPlanes = 1
	bmi\bmiHeader\biBitCount = 32
	If bm\bmBitsPixel = 24
		bmi\bmiHeader\biCompression = #BI_RGB
	EndIf
	
	Mem = AllocateMemory(bm\bmWidth * bm\bmHeight * 4)
	If Mem
		
		hdc = CreateCompatibleDC_(GetDC_(ImageID))
		If hdc
			GetDIBits_(hdc, ImageID, 0, bm\bmHeight, Mem, @bmi, #DIB_RGB_COLORS) ; on envoie la liste dans l'image
			DeleteDC_(hdc)
			Resultat = ImageID
		EndIf
		
		; On convertit la liste dans le bon format
		Temp1 = bm\bmHeight - 1
		Temp2 = bm\bmWidth - 1
		For nn = 0 To Temp2
			For n = 0 To Temp1
				Temp3 = Mem + (nn + (Temp1 - n) * bm\bmWidth) * 4
				PokeL(HList, PeekL(Temp3))
				PokeB(HList + 2, PeekB(Temp3))
				PokeB(HList, PeekB(Temp3 + 2))
				HList + 4
			Next
		Next
		
		FreeMemory(Mem)
	EndIf
	
	ProcedureReturn Resultat
EndProcedure

ProcedureDLL.i PivoterImage(ImageID.i, Angle.i) ; Rotation d'une image d'un angle multiple de 90°
	Protected bmi.BITMAPINFO, hdc.i, NewImageID.i, Mem.i, Mem2, MemTemp.i, n.i, nn.i, bm.BITMAP, Temp1.i, Temp2.i
	
	NewImageID = 0
	
	If Angle <= 0
		Angle = 360 + Angle
	EndIf
	
	; On récupère la taille de l'image
	GetObject_(ImageID, SizeOf(BITMAP), @bm.BITMAP)
	
	If Angle = 90 Or Angle = 180 Or Angle = 270
		
		; on prépare les infos pour récupérer l'image sous forme d'adresse mémoire
		bmi\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
		bmi\bmiHeader\biWidth = bm\bmWidth
		bmi\bmiHeader\biHeight = bm\bmHeight
		bmi\bmiHeader\biPlanes = 1
		bmi\bmiHeader\biBitCount = 32
		If bm\bmBitsPixel = 24
			bmi\bmiHeader\biCompression = #BI_RGB
		EndIf
		
		; On alloue 2 espace mémoire pour recevoir l'image d'origine et l'image pivotée
		Mem = AllocateMemory(bm\bmWidth * bm\bmHeight * 4)
		If Mem
			Mem2 = AllocateMemory(bm\bmWidth * bm\bmHeight * 4)
			If Mem2
				
				; On récupère l'image dans un espace mémoire
				hdc = CreateCompatibleDC_(GetDC_(ImageID))
				If hdc
					GetDIBits_(hdc, ImageID, 0, bm\bmHeight, Mem, @bmi, #DIB_RGB_COLORS) ; on envoie la liste dans l'image
					DeleteDC_(hdc)
				EndIf
				
				MemTemp = Mem
				
				; On fait la rotation de l'image de 90, 180 ou 270°
				Select Angle
					Case 90 ; rotation de 90°
						Temp1 = bm\bmWidth - 1
						; Pour chaque point de l'image
						For n = 0 To bm\bmHeight - 1
							For nn = Temp1 To 0 Step -1
								PokeL(Mem2 + (n + nn * bm\bmHeight) * 4, PeekL(MemTemp)) ; On fait une rotation de 90°
								MemTemp + 4
								; Le * 4 vient du fait qu'on manipule des long
							Next
						Next
						; On inverse la largeur et la hauteur de l'image
						Temp1 = bm\bmHeight : bm\bmHeight = bm\bmWidth : bm\bmWidth = Temp1
						bmi\bmiHeader\biWidth = bm\bmWidth
						bmi\bmiHeader\biHeight = bm\bmHeight
						; On crée la nouvelle image vierge
						NewImageID = CreateImage(#PB_Any, bm\bmWidth, bm\bmHeight, bm\bmBitsPixel)
						
					Case 180
						Temp1 = Mem2 + bm\bmWidth * bm\bmHeight * 4 - 4
						For nn = 0 To bm\bmWidth - 1
							For n = 0 To bm\bmHeight - 1
								PokeL(Temp1 - Temp2, PeekL(Mem + Temp2))
								Temp2 + 4
							Next
						Next
						NewImageID = CreateImage(#PB_Any, bm\bmWidth, bm\bmHeight, bm\bmBitsPixel)
						
					Case 270
						Temp1 = bm\bmHeight - 1
						For n = Temp1 To 0 Step -1
							For nn = 0 To bm\bmWidth - 1
								PokeL(Mem2 + (n + nn * bm\bmHeight) * 4, PeekL(MemTemp))
								MemTemp + 4
							Next
						Next
						Temp1 = bm\bmHeight : bm\bmHeight = bm\bmWidth : bm\bmWidth = Temp1
						bmi\bmiHeader\biWidth = bm\bmWidth
						bmi\bmiHeader\biHeight = bm\bmHeight
						NewImageID = CreateImage(#PB_Any, bm\bmWidth, bm\bmHeight, bm\bmBitsPixel)
						
				EndSelect
				
				; On copie l'espace mémoire qui contient l'image pivotée dans la nouvelle image créée
				hdc = CreateCompatibleDC_(GetDC_(ImageID(NewImageID)))
				If hdc
					SetDIBits_(hdc, ImageID(NewImageID), 0, bm\bmHeight, Mem2, @bmi, #DIB_RGB_COLORS) ; on envoie la liste dans l'image
					DeleteDC_(hdc)
				EndIf
				
				; On libère la mémoire
				FreeMemory(Mem2)
			EndIf
			FreeMemory(Mem)
		EndIf
		
	ElseIf Angle = 360
		NewImageID = CreateImage(#PB_Any, bm\bmWidth, bm\bmHeight, bm\bmBitsPixel)
		StartDrawing(ImageOutput(NewImageID))
		DrawingMode(#PB_2DDrawing_AlphaChannel)
		Box(0, 0, bm\bmWidth, bm\bmHeight, $00000000)
		DrawingMode(#PB_2DDrawing_AlphaBlend)
		DrawImage(ImageID, 0, 0)
		StopDrawing()
	EndIf
	
	ProcedureReturn NewImageID
EndProcedure

ProcedureDLL.i PivoterImageEx(ImageID.i, Angle.f) ; Rotation d'une image d'un angle en °
	Protected bmi.BITMAPINFO, bmi2.BITMAPINFO, hdc.i, NewImageID.i, Mem.i, Mem2.i, n.i, nn.i, bm.BITMAP, Cos.f, Sin.f, CouleurFond.i
	Protected CX1.i, CY1.i, CX2.i, CY2.i, Mem01.i, Mem10.i, Mem11.i, Mem2Temp.i, x1b.i, X2b.i, y1b.i, Y2b.i, X1.f, X2.i, Y1.f, Y2.i, Temp1.f, Temp2.f
	Protected fx.f, fy.f, f00.f, f01.f, f10.f, f11.f, MemTemp.i, c00.l, c01.l, c10.l, c11.l, Canal00.l, Canal01.l, Canal10.l, Canal11.l, Alpha.l
	Protected Rouge.i, Vert.i, Bleu.i
	
	Angle = Angle * #PI / 180 ; On convertit en radian
	
	Cos = Cos(Angle)
	Sin = Sin(Angle)
	
	CouleurFond = 0
	
	GetObject_(ImageID, SizeOf(BITMAP), @bm.BITMAP)
	
	bmi\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
	bmi\bmiHeader\biWidth = bm\bmWidth
	bmi\bmiHeader\biHeight = bm\bmHeight
	bmi\bmiHeader\biPlanes = 1
	bmi\bmiHeader\biBitCount = 32
	If bm\bmBitsPixel = 24
		bmi\bmiHeader\biCompression = #BI_RGB
	EndIf
	
	bmi2\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
	bmi2\bmiHeader\biWidth = Round(bm\bmWidth * Abs(Cos) + bm\bmHeight * Abs(Sin), 1)
	bmi2\bmiHeader\biHeight = Round(bm\bmHeight * Abs(Cos) + bm\bmWidth * Abs(Sin), 1)
	bmi2\bmiHeader\biPlanes = 1
	bmi2\bmiHeader\biBitCount = 32
	If bm\bmBitsPixel = 24
		bmi\bmiHeader\biCompression = #BI_RGB
	EndIf
	
	Mem = AllocateMemory(bm\bmWidth * bm\bmHeight * 4)
	If Mem
		Mem2 = AllocateMemory(bmi2\bmiHeader\biWidth * bmi2\bmiHeader\biHeight * 4)
		If Mem2
			
			hdc = CreateCompatibleDC_(GetDC_(ImageID))
			If hdc
				GetDIBits_(hdc, ImageID, 0, bm\bmHeight, Mem, @bmi, #DIB_RGB_COLORS) ; on envoie la liste dans l'image
				DeleteDC_(hdc)
			EndIf
			
			CX1 = bm\bmWidth - 1
			CY1 = bm\bmHeight - 1
			CX2 = bmi2\bmiHeader\biWidth - 1
			CY2 = bmi2\bmiHeader\biHeight - 1
			
			Mem01 = Mem + bm\bmWidth * 4
			Mem10 = Mem + 4
			Mem11 = Mem01 + 4
			
			Mem2Temp = Mem2
			
			For nn = 0 To CY2
				y1b = nn * 2 - CY2
				Temp1 = CX1 - y1b * Sin
				Temp2 = CY1 + y1b * Cos
				For n = 0 To CX2
					x1b = n * 2 - CX2
					
					x1 = (Temp1 + x1b * Cos) / 2
					y1 = (Temp2 + x1b * Sin) / 2
					
					x2 = x1
					y2 = y1
					
					If x1 < x2
						x2-1
					EndIf
					If y1 < y2
						y2-1
					EndIf
					
					x2b = x2 + 1
					y2b = y2 + 1
					
					If x2b >= 0 And x2 <= CX1 And y2b >= 0 And y2 <= CY1 ; On filtre si on est complétement en dehors de l'image
						
						fx = x1 - x2
						fy = y1 - y2
						f00 = (1 - fx) * (1 - fy)
						f01 = (1 - fx) * fy
						f10 = fx * (1 - fy)
						f11 = fx * fy
						
						MemTemp = (x2 + y2 * bm\bmWidth) * 4
						
						If x2 >= 0 And x2 <= CX1
							If y2 >= 0 And y2 <= CY1
								c00 = PeekL(Mem + MemTemp)
							Else
								c00 = 0
							EndIf
							If y2b >= 0 And y2b <= CY1
								c01 = PeekL(Mem01 + MemTemp)
							Else
								c01 = 0
							EndIf
						Else
							c00 = 0
							c01 = 0
						EndIf
						If x2b >= 0 And x2b <= CX1
							If y2 >= 0 And y2 <= CY1
								c10 = PeekL(Mem10 + MemTemp)
							Else
								c10 = 0
							EndIf
							If  y2b >= 0 And y2b <= CY1
								c11 = PeekL(Mem11 + MemTemp)
							Else
								c11 = 0
							EndIf
						Else
							c10 = 0
							c11 = 0
						EndIf
						
						Canal00 = c00 >> 24 & $FF
						Canal01 = c01 >> 24 & $FF
						Canal10 = c10 >> 24 & $FF
						Canal11 = c11 >> 24 & $FF
						Alpha = Canal00 * f00 + Canal01 * f01 + Canal10 * f10 + Canal11 * f11
						Canal00 = c00 >> 16 & $FF
						Canal01 = c01 >> 16 & $FF
						Canal10 = c10 >> 16 & $FF
						Canal11 = c11 >> 16 & $FF
						Rouge = Canal00 * f00 + Canal01 * f01 + Canal10 * f10 + Canal11 * f11
						Canal00 = c00 >> 8 & $FF
						Canal01 = c01 >> 8 & $FF
						Canal10 = c10 >> 8 & $FF
						Canal11 = c11 >> 8 & $FF
						Vert = Canal00 * f00 + Canal01 * f01 + Canal10 * f10 + Canal11 * f11
						Canal00 = c00 & $FF
						Canal01 = c01 & $FF
						Canal10 = c10 & $FF
						Canal11 = c11 & $FF
						Bleu = Canal00 * f00 + Canal01 * f01 + Canal10 * f10 + Canal11 * f11
						
						PokeL(Mem2Temp, Rouge | Vert << 8 | Bleu << 16 | Alpha << 24)
						
					Else
						PokeL(Mem2Temp, 0)
					EndIf
					
					Mem2Temp + 4
					
				Next
			Next
			
			; On crée la nouvelle image
			NewImageID = CreateImage(#PB_Any, bmi2\bmiHeader\biWidth, bmi2\bmiHeader\biHeight, bm\bmBitsPixel)
			hdc = CreateCompatibleDC_(GetDC_(ImageID(NewImageID)))
			If hdc
				SetDIBits_(hdc, ImageID(NewImageID), 0, bmi2\bmiHeader\biHeight, Mem2, @bmi2, #DIB_RGB_COLORS) ; on envoie la liste dans l'image
				DeleteDC_(hdc)
			EndIf
			
			FreeMemory(Mem2)
		EndIf
		FreeMemory(Mem)
	EndIf
	
	ProcedureReturn NewImageID
EndProcedure

ProcedureDLL.i PivoterImageEx2(ImageID.i, Angle.f, mode.i) ; Rotation d'une image d'un angle en °
	Protected bmi.BITMAPINFO, bmi2.BITMAPINFO, hdc.i, NewImageID.i, Mem.i, n.i, nn.i, bm.BITMAP, Cos.f, Sin.f, CouleurFond.i, Mem2.i, MemTemp.i
	Protected Mem01.l, Mem10.l, Mem11.l, Mem2Temp.i, CX1.i, CX2.i, CY1.i, CY2.i, X1b.i, X2b.i, Y1b.i, Y2b.i, Temp1.f, Temp2.f, x1.f, x2.i, y1.f, y2.i, fx.f, fy.f
	Protected f00.f, f01.f, f10.f, f11.f, c00.i, c01.i, c10.i, c11.i, Canal00.i, Canal01.i, Canal10.i, Canal11.i, Alpha.i, Rouge.i, Vert.i, Bleu.i
	
	Angle = Angle * #PI / 180 ; On convertit en radian
	
	Cos = Cos(Angle)
	Sin = Sin(Angle)
	
	CouleurFond = 0
	
	GetObject_(ImageID, SizeOf(BITMAP), @bm.BITMAP)
	
	bmi\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
	bmi\bmiHeader\biWidth = bm\bmWidth
	bmi\bmiHeader\biHeight = bm\bmHeight
	bmi\bmiHeader\biPlanes = 1
	bmi\bmiHeader\biBitCount = 32
	If bm\bmBitsPixel = 24
		bmi\bmiHeader\biCompression = #BI_RGB
	EndIf
	
	bmi2\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
	Select mode
		Case 1
			bmi2\bmiHeader\biWidth = bm\bmWidth
			bmi2\bmiHeader\biHeight = bm\bmHeight
		Case 2
			bmi2\bmiHeader\biWidth = Round(Sqr(bm\bmWidth * bm\bmWidth + bm\bmHeight * bm\bmHeight), 1)
			bmi2\bmiHeader\biHeight = bmi2\bmiHeader\biWidth
		Default
			bmi2\bmiHeader\biWidth = Round(bm\bmWidth * Abs(Cos) + bm\bmHeight * Abs(Sin), 1)
			bmi2\bmiHeader\biHeight = Round(bm\bmHeight * Abs(Cos) + bm\bmWidth * Abs(Sin), 1)
	EndSelect
	bmi2\bmiHeader\biPlanes = 1
	bmi2\bmiHeader\biBitCount = 32
	
	Mem = AllocateMemory(bm\bmWidth * bm\bmHeight * 4)
	If Mem
		Mem2 = AllocateMemory(bmi2\bmiHeader\biWidth * bmi2\bmiHeader\biHeight * 4)
		If Mem2
			
			hdc = CreateCompatibleDC_(GetDC_(ImageID))
			If hdc
				GetDIBits_(hdc, ImageID, 0, bm\bmHeight, Mem, @bmi, #DIB_RGB_COLORS) ; on envoie la liste dans l'image
				DeleteDC_(hdc)
			EndIf
			
			CX1 = bm\bmWidth - 1
			CY1 = bm\bmHeight - 1
			CX2 = bmi2\bmiHeader\biWidth - 1
			CY2 = bmi2\bmiHeader\biHeight - 1
			
			Mem01 = Mem + bm\bmWidth * 4
			Mem10 = Mem + 4
			Mem11 = Mem01 + 4
			
			Mem2Temp = Mem2
			
			For nn = 0 To CY2
				y1b = nn * 2 - CY2
				Temp1 = CX1 - y1b * Sin
				Temp2 = CY1 + y1b * Cos
				For n = 0 To CX2
					x1b = n * 2 - CX2
					
					x1 = (Temp1 + x1b * Cos) / 2
					y1 = (Temp2 + x1b * Sin) / 2
					
					x2 = x1
					y2 = y1
					
					If x1 < x2
						x2-1
					EndIf
					If y1 < y2
						y2-1
					EndIf
					
					x2b = x2 + 1
					y2b = y2 + 1
					
					If x2b >= 0 And x2 <= CX1 And y2b >= 0 And y2 <= CY1 ; On filtre si on est complétement en dehors de l'image
						
						fx = x1 - x2
						fy = y1 - y2
						f00 = (1 - fx) * (1 - fy)
						f01 = (1 - fx) * fy
						f10 = fx * (1 - fy)
						f11 = fx * fy
						
						MemTemp = (x2 + y2 * bm\bmWidth) * 4
						
						If x2 >= 0 And x2 <= CX1
							If y2 >= 0 And y2 <= CY1
								c00 = PeekL(Mem + MemTemp)
							Else
								c00 = 0
							EndIf
							If y2b >= 0 And y2b <= CY1
								c01 = PeekL(Mem01 + MemTemp)
							Else
								c01 = 0
							EndIf
						Else
							c00 = 0
							c01 = 0
						EndIf
						If x2b >= 0 And x2b <= CX1
							If y2 >= 0 And y2 <= CY1
								c10 = PeekL(Mem10 + MemTemp)
							Else
								c10 = 0
							EndIf
							If  y2b >= 0 And y2b <= CY1
								c11 = PeekL(Mem11 + MemTemp)
							Else
								c11 = 0
							EndIf
						Else
							c10 = 0
							c11 = 0
						EndIf
						
						Canal00 = c00 >> 24 & $FF
						Canal01 = c01 >> 24 & $FF
						Canal10 = c10 >> 24 & $FF
						Canal11 = c11 >> 24 & $FF
						Alpha = Canal00 * f00 + Canal01 * f01 + Canal10 * f10 + Canal11 * f11
						Canal00 = c00 >> 16 & $FF
						Canal01 = c01 >> 16 & $FF
						Canal10 = c10 >> 16 & $FF
						Canal11 = c11 >> 16 & $FF
						Rouge = Canal00 * f00 + Canal01 * f01 + Canal10 * f10 + Canal11 * f11
						Canal00 = c00 >> 8 & $FF
						Canal01 = c01 >> 8 & $FF
						Canal10 = c10 >> 8 & $FF
						Canal11 = c11 >> 8 & $FF
						Vert = Canal00 * f00 + Canal01 * f01 + Canal10 * f10 + Canal11 * f11
						Canal00 = c00 & $FF
						Canal01 = c01 & $FF
						Canal10 = c10 & $FF
						Canal11 = c11 & $FF
						Bleu = Canal00 * f00 + Canal01 * f01 + Canal10 * f10 + Canal11 * f11
						
						PokeL(Mem2Temp, Rouge | Vert << 8 | Bleu << 16 | Alpha << 24)
						
					Else
						PokeL(Mem2Temp, 0)
					EndIf
					
					Mem2Temp + 4
					
				Next
			Next
			
			; On crée la nouvelle image
			NewImageID = CreateImage(#PB_Any, bmi2\bmiHeader\biWidth, bmi2\bmiHeader\biHeight, bm\bmBitsPixel)
			hdc = CreateCompatibleDC_(GetDC_(ImageID(NewImageID)))
			If hdc
				SetDIBits_(hdc, ImageID(NewImageID), 0, bmi2\bmiHeader\biHeight, Mem2, @bmi2, #DIB_RGB_COLORS) ; on envoie la liste dans l'image
				DeleteDC_(hdc)
			EndIf
			
			FreeMemory(Mem2)
		EndIf
		FreeMemory(Mem)
	EndIf
	
	ProcedureReturn NewImageID
EndProcedure

ProcedureDLL.i SymetrieH(ImageID.i) ; Symétrie horizontale de l'image
	Protected bmi.BITMAPINFO, hdc.i, NewImageID.i, Mem.i, Mem2.i, MemTemp.i, n.i, nn.i, bm.BITMAP
	
	NewImageID = 0
	
	GetObject_(ImageID, SizeOf(BITMAP), @bm.BITMAP)
	
	bmi\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
	bmi\bmiHeader\biWidth = bm\bmWidth
	bmi\bmiHeader\biHeight = bm\bmHeight
	bmi\bmiHeader\biPlanes = 1
	bmi\bmiHeader\biBitCount = 32
	If bm\bmBitsPixel = 24
		bmi\bmiHeader\biCompression = #BI_RGB
	EndIf
	
	Mem = AllocateMemory(bm\bmWidth * bm\bmHeight * 4)
	If Mem
		Mem2 = AllocateMemory(bm\bmWidth * bm\bmHeight * 4)
		If Mem2
			
			hdc = CreateCompatibleDC_(GetDC_(ImageID))
			If hdc
				GetDIBits_(hdc, ImageID, 0, bm\bmHeight, Mem, @bmi, #DIB_RGB_COLORS) ; on envoie la liste dans l'image
				DeleteDC_(hdc)
			EndIf
			
			MemTemp = Mem
			
			; On fait la symétrie
			For n = 0 To bm\bmHeight - 1
				For nn = 0 To bm\bmWidth - 1
					PokeL(Mem2 + (nn + (bm\bmHeight - 1 - n) * bm\bmWidth) * 4, PeekL(MemTemp))
					MemTemp + 4
				Next
			Next
			
			; on crée la nouvelle image
			NewImageID = CreateImage(#PB_Any, bm\bmWidth, bm\bmHeight, bm\bmBitsPixel)
			hdc = CreateCompatibleDC_(GetDC_(ImageID(NewImageID)))
			If hdc
				SetDIBits_(hdc, ImageID(NewImageID), 0, bm\bmHeight, Mem2, @bmi, #DIB_RGB_COLORS) ; on envoie la liste dans l'image
				DeleteDC_(hdc)
			EndIf
			
			FreeMemory(Mem2)
		EndIf
		FreeMemory(Mem)
	EndIf
	
	ProcedureReturn NewImageID
EndProcedure

ProcedureDLL.i SymetrieV(ImageID.i) ; Symétrie verticale de l'image
	Protected bmi.BITMAPINFO, hdc.i, NewImageID.i, Mem.i, Mem2.i, MemTemp.i, n.i, nn.i, bm.BITMAP
	
	NewImageID = 0
	
	GetObject_(ImageID, SizeOf(BITMAP), @bm.BITMAP)
	
	bmi\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
	bmi\bmiHeader\biWidth = bm\bmWidth
	bmi\bmiHeader\biHeight = bm\bmHeight
	bmi\bmiHeader\biPlanes = 1
	bmi\bmiHeader\biBitCount = 32
	If bm\bmBitsPixel = 24
		bmi\bmiHeader\biCompression = #BI_RGB
	EndIf
	
	Mem = AllocateMemory(bm\bmWidth * bm\bmHeight * 4)
	If Mem
		Mem2 = AllocateMemory(bm\bmWidth * bm\bmHeight * 4)
		If Mem2
			
			hdc = CreateCompatibleDC_(GetDC_(ImageID))
			If hdc
				GetDIBits_(hdc, ImageID, 0, bm\bmHeight, Mem, @bmi, #DIB_RGB_COLORS) ; on envoie la liste dans l'image
				DeleteDC_(hdc)
			EndIf
			
			MemTemp = Mem
			
			; On fait la symétrie
			For n = 0 To bm\bmHeight - 1
				For nn = 0 To bm\bmWidth - 1
					PokeL(Mem2 + (bm\bmWidth - 1 - nn + n * bm\bmWidth) * 4, PeekL(MemTemp))
					MemTemp + 4
				Next
			Next
			
			; on crée la nouvelle image
			NewImageID = CreateImage(#PB_Any, bm\bmWidth, bm\bmHeight, bm\bmBitsPixel)
			hdc = CreateCompatibleDC_(GetDC_(ImageID(NewImageID)))
			If hdc
				SetDIBits_(hdc, ImageID(NewImageID), 0, bm\bmHeight, Mem2, @bmi, #DIB_RGB_COLORS) ; on envoie la liste dans l'image
				DeleteDC_(hdc)
			EndIf
			
			FreeMemory(Mem2)
		EndIf
		FreeMemory(Mem)
	EndIf
	
	ProcedureReturn NewImageID
EndProcedure

ProcedureDLL TSL(Teinte.i, Saturation.i, Luminosite.i) ; TSL (Teinte, Saturation, Luminosité) ; renvoye la couleur au format RGB
	Protected fTeinte.f, Minimum.i, Maximum.i, Difference.i, i.i, Rouge.i, Vert.i, Bleu.i
	fTeinte = 6*Teinte/240
	If Luminosite =< 120
		Maximum = Round((255*Luminosite*(1+Saturation/240)/240), #PB_Round_Nearest)
		Minimum = Round((255*Luminosite*(1-Saturation/240)/240), #PB_Round_Nearest)
	Else
		Maximum = Round((255*(Luminosite*(1-Saturation/240)/240+Saturation/240)), #PB_Round_Nearest)
		Minimum = Round((255*(Luminosite*(1+Saturation/240)/240-Saturation/240)), #PB_Round_Nearest)
	EndIf
	Difference = Maximum-Minimum
	i = Round(fTeinte, #PB_Round_Nearest)
	If i = 0
		Rouge = Maximum : Vert = Minimum+fTeinte*Difference : Bleu = Minimum
	ElseIf i = 1
		Rouge = Minimum + (2-fTeinte)*Difference : Vert = Maximum : Bleu = Minimum
	ElseIf i = 2
		Rouge = Minimum : Vert = Maximum : Bleu = Minimum+(fTeinte-2)*Difference
	ElseIf i = 3
		Rouge = Minimum : Vert = Minimum+(4-fTeinte)*Difference : Bleu = Maximum
	ElseIf i = 4
		Rouge = Minimum + (fTeinte-4)*Difference : Vert = Minimum : Bleu = Maximum
	Else
		Rouge = Maximum : Vert = Minimum : Bleu = Minimum+(6-fTeinte)*Difference
	EndIf
	ProcedureReturn RGB(Rouge,Vert,Bleu)
EndProcedure
J'espère que ce sera assez complet.

Re: Modifier les couleurs d'une image

Publié : dim. 20/oct./2013 8:45
par blendman
Merci pour vos commentaires, ça me sera utile ;).

Dobro : je pensais à la même chose pour la luminosité et le contraste, donc c'est cool, ça va bien me servir ;).

Ar-s : je connaissais l'inversion, car dans mon logiciel TEO, j'ai déjà les transformations d'image : inversion des couleur, désaturation et maintenant balance des couleurs (avec ce soucis lié à la luminosité)

MIcoute : je connais les codes de LSI. Le problème est qu'ils ne sont pas multi-plateformes. OR, pour le moment, mon code (8500 lignes environ) utilise une seule fois une API windows (pour la rotation de la brosse) et j'ai trouvé l'équivalent Linux et sans doute Mac pour ça.
J'essaie donc d'éviter d'utiliser des API autant que possible. Comme ça, lorsque j'en aurai l'occasion, je pourrais compiler pour Linux et Mac :).

Pour la balance des couleurs, j'ai regardé Photoshop, et voici comment il procède :
- en haut, on a trois sortes de tracksbar pour le changement des couleurs
- en bas, on a 3 options pour le type de luminosités : shadows, tons moyens et ton lumineux. En choisissant chaque type de luminosité, on agit sur les pixels de cette luminosité.

Je me demande s'ils ne modifient pas comme ceci :
Tons shadows, on modifie uniquement les pixels <= rgb(80,80,80)
Ton moyens, on modifie uniquement les pixels > 80 et <= 160
Ton lumineux, on modifie uniquement les pixels > 160 et < 240
ça laisse les pixels presque blancs (>240) tel quels

Pour préserver la luminosité, je pense qu'on peut la calculer (comme pour la désaturation) :
(r+g+b)/3
Et on vérifie si on est proche de celle-ci avec les nouvelles modifications. Si ce n'est pas le cas, on doit pouvoir modifier le pixel pour rétablir une luminosité proche de celle de base.

On peut aussi préserver la luminosité