INVERSE DE RGB

balgrim Messages postés 52 Date d'inscription vendredi 26 avril 2002 Statut Membre Dernière intervention 28 octobre 2003 - 6 août 2002 à 00:04
cs_grandvizir Messages postés 1106 Date d'inscription samedi 8 novembre 2003 Statut Membre Dernière intervention 3 septembre 2006 - 21 mai 2005 à 10:07
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/12080-inverse-de-rgb

cs_grandvizir Messages postés 1106 Date d'inscription samedi 8 novembre 2003 Statut Membre Dernière intervention 3 septembre 2006 22
21 mai 2005 à 10:07
Résumons le principe simplement:

Red => 255-Red;
Green => 255-Green;
Blue => 255-Blue;

Ca donne la couleur inverse...
balgrim Messages postés 52 Date d'inscription vendredi 26 avril 2002 Statut Membre Dernière intervention 28 octobre 2003
6 août 2002 à 00:04
ok je vais voir ça, et encore merci!

Balgrim.
balgrim Messages postés 52 Date d'inscription vendredi 26 avril 2002 Statut Membre Dernière intervention 28 octobre 2003
5 août 2002 à 23:35
heu encore,

j'ai vu que tu savais maitriser la fonction scanline.
cependant g pas tous compris a comment sa marche:

est-ce que par exemple:
a:=bmp.ScanLine[bmpSource.height-1]
renvoi tous les pixel d'une image??
en fait sa m'arrangerai :o)

Enfin bon bref...*ne nous eloignons pas de ma source ;)*

Voila,bye

Balgrim.
balgrim Messages postés 52 Date d'inscription vendredi 26 avril 2002 Statut Membre Dernière intervention 28 octobre 2003
5 août 2002 à 23:25
hé beh, je vois ke ma source n'est pas passé inaperçu :o).
C vrai que c pas top mais je debute en asm --> raisons de plus pour te remercier pour tous tes conseil.
Bon ya quelque truc ke je voudrait te demander sur ce que tu a ecrit:
-pour le type record, sa serai pas plus simple de faire
mov MonRGB.R,ecx; (a moi que sa marche po)

Il faut dire que la j'ai de coi optimisé mon code :)

bah encore merci, je vais rectifier tout de suite la version pascal :o) (j'avais pas utilisé)
cs_Nono40 Messages postés 962 Date d'inscription mercredi 3 avril 2002 Statut Membre Dernière intervention 12 septembre 2006 2
5 août 2002 à 23:08
Allez pendant que j'y suis encore un petit commentaire pour continuer sur les Procédures en assembleur.

Si on veut faire une fonction plutôt qu'une procédure, il faut procéder comme suit :
function RGBFromLongASM(Couleur:TColor):TMonRGB;Pascal; //version asm
asm
xor ecx,ecx
mov eax,couleur
//rouge
mov cl,al
mov edx,@Result
mov TMonRGB([edx]).R,ecx
//vert
mov cl,ah
mov TMonRGB([edx]).G,ecx
//bleu
shr eax,16
mov cl,al
mov TMonRGB([edx]).B,ecx
end;

Comme le type du résultat ( TMonRGB ) n'est pas scalaire, il faut remplir les champs du TMonRGB à l'aide de l'adresse de Result : Mov EDX,@result. Ensuite c'est la même chose.
Attention : quand une fonction retourne un type scalaire ( comme CHAR,INTEGER au autre ), alors la valeur de retour est à passer dans le registre AL,AX ou EAX.

Nono.
cs_Nono40 Messages postés 962 Date d'inscription mercredi 3 avril 2002 Statut Membre Dernière intervention 12 septembre 2006 2
5 août 2002 à 22:58
Ah, aussi pour répondre à ta demande avec un type composé RECORD :
Type TMonRGB = Record
R:Integer;
G:Integer;
B:Integer;
End;

procedure RGBFromLongASM(Couleur:TColor;Var MonRGB:TMonRGB);Pascal; //version asm
asm
xor ecx,ecx
mov eax,couleur
//rouge
mov cl,al
mov edx,MonRGB
mov TMonRGB([edx]).R,ecx
//vert
mov cl,ah
mov TMonRGB([edx]).G,ecx
//bleu
shr eax,16
mov cl,al
mov TMonRGB([edx]).B,ecx
end;

Delphi autorise l'utilisation des type pour calculer les déclages dans les instructions assembleur : TMonRGB([EDX]).G permet à partir de l'adresse de base contenu dans EDX de calculer le déplacement supplémentaire avec .G. C'est mieux qye d'écrir [EDX+4] car on reste indépendant des directives d'alignement des variables.

La procédure en Pascal dans ce cas-ci ne change pas beaucoup :
procedure RGBFromLongPascal(Couleur:TColor;Var MonRGB:TMonRGB);
begin
MonRGB.B:=(Couleur And $00FF0000) Shr 16;
MonRGB.G:=(Couleur And $0000FF00) Shr 8;
MonRGB.R:=(Couleur And $000000FF);
end;

Nono.
cs_Nono40 Messages postés 962 Date d'inscription mercredi 3 avril 2002 Statut Membre Dernière intervention 12 septembre 2006 2
5 août 2002 à 22:45
En fait l'utilisation de variables globales pour stocker le résultat de la fonction n'est pas une habitude à prendre. Il vaut mieux passer des paramètres par variables, c'est plus pratique à utiliser ensuite :
procedure RGBFromLongASM(Couleur:TColor;Var Rouge,Vert,Bleu:Integer);Pascal; //version asm
asm
xor ecx,ecx
mov eax,couleur
//rouge
mov cl,al
mov edx,rouge
mov Dword ptr[edx],ecx
//vert
mov cl,ah
mov edx,vert
mov Dword ptr[edx],ecx
//bleu
shr eax,16
mov cl,al
mov edx,bleu
mov Dword ptr[edx],ecx
end;

Note la directive de compilation PASCAL, elle permet de forcer Delphi à ne pas utliser les registres comme paramètres, c'est plus clair quand on programme en assembleur. Il n'est pas alors utile de connaitre les règles d'optimisation par registre.

Le code de la version Pascal de ta procédure est le même dans ce cas.

Nono.
cs_Nono40 Messages postés 962 Date d'inscription mercredi 3 avril 2002 Statut Membre Dernière intervention 12 septembre 2006 2
5 août 2002 à 19:53
J'ai quelques remarques :

*** Méthode assembleur :
Ton prindipe d'extraction des couleurs est bien compliqué : n'oublie pas que AL est l'octet de poids faible de EAX AH l'octet de poids fort de AX, AX étant le mot de poids faible de EAX. Donc quand tu charges Couleur dans EAX tu trouves directement :
Le bleu dans le mot de poids fort de EAX
Le vert dans AH !!!
Le rouge dans AL !!!
Donc ta procédure peut ce réduire à :
procedure RGBFromLongASM(Couleur:TColor); //version asm
asm
push eax
mov eax,couleur
//rouge
mov rouge,al
//vert
mov vert,ah
//bleu
shr eax,16
mov bleu,al
pop eax
end;

*** Méthode Pascal :
Ton source ne compile pas ! Pour les division c'est le signe / et non le signe de plus tu travail sur des entiers donc il faut utiliser DIV plutôt que / car ça évite un temps de cycle cosidérable pour les conversion entiers/flotant.
Il vaudrait mieux travailler sur des masques, c'est plus rapide et plus clair :
procedure RGBFromLongPascal(Couleur:TColor); //d'apres le code de fabiin sur un forum vb :)
begin
Bleu:=(Couleur And $00FF0000) Shr 16;
Vert:=(Couleur And $0000FF00) Shr 8;
Rouge =(Couleur And $000000FF);
end;

Nono.
Rejoignez-nous