UNIT POSITION_BY_COLOR

cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 - 27 déc. 2005 à 18:45
DeltaFX Messages postés 449 Date d'inscription lundi 19 avril 2004 Statut Membre Dernière intervention 8 avril 2009 - 8 févr. 2006 à 20:46
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/35264-unit-position-by-color

DeltaFX Messages postés 449 Date d'inscription lundi 19 avril 2004 Statut Membre Dernière intervention 8 avril 2009 2
8 févr. 2006 à 20:46
Arf, j'avais juste posté les modifs en commentaire,pas updaté le source. C'est corrigé.
Ne t'inquiète pas à propos de la remarque de Wolf. ça doit être sa cloche qui lui est tombé sur la tete (ou sur ses "oeux") ...

Sinon, je ne vois pas où est l'amélioration (pourtant j'imagine qu'il y en a une) par rapport à la version précédente. Merci d'avance si tu pouvais m'éclairer ...
DeltaFX Messages postés 449 Date d'inscription lundi 19 avril 2004 Statut Membre Dernière intervention 8 avril 2009 2
6 févr. 2006 à 16:20
Mais kékidi lui ? Le prog on s'en tape, c'est l'unit Poisition-by-color qui est importante. Or elle est mature là.

J'ai juste ajouter ca :
//--------------------------------------------------------
function GetBoundRect(aColor:TColor; var aRect: TRect): boolean;
var i:integer;

begin
Result:=False;
for i:=0 to MaxUsed do
if AreaColorList[i].Color = aColor then
begin
aRect:=AreaColorList[i].Rect;
Result:=True;
break;
end;

end;

//--------------------------------------------------------
procedure PlaceCtrl(const Ctrl: TControl);
var
R: TRect;
begin
if GetBoundRect(Ctrl.Tag, R) then
begin
Ctrl.BoundsRect:=R;
end;
end;


Histoire de faire plus dense.

Tu peux clarifier ta remarque WOlf691300 ?
wolf691300 Messages postés 41 Date d'inscription mardi 15 juin 2004 Statut Membre Dernière intervention 31 mars 2006
22 janv. 2006 à 18:45
Pour améliorer ton programme, y placer un peu de finesse dans son ensemble, j'y vois une représentation fort grossière dans le graphisme. Aller améliore ...Et bonne continuation ... J'ai l'impression de voir des oeux déposé par des cloches ...

Wolf691300 + Joyeuses Pâques ...
f0xi Messages postés 4205 Date d'inscription samedi 16 octobre 2004 Statut Modérateur Dernière intervention 12 mars 2022 35
14 janv. 2006 à 21:15
ton programme, amelioré c'est encore.
fier de toi, mon jeune ami je suis.

une bonne année a tous je vous souhaite.
DeltaFX Messages postés 449 Date d'inscription lundi 19 avril 2004 Statut Membre Dernière intervention 8 avril 2009 2
3 janv. 2006 à 00:19
Je l'ai réécrit comme ca :

procedure PlaceCtrl(const Ctrl: TControl);
var
R: TRect;
begin
if GetTLWH(Ctrl.Tag, R) then
begin
Ctrl.Left := R.Left;
Ctrl.Top := R.Top;
Ctrl.Width := R.Right;
Ctrl.Height := R.Bottom;
end;
end;


procedure BrowseControls(const Main: TWinControl);
var
I: Integer;
begin
for I := 0 to Main.ControlCount -1 do
if Main.Controls[I].Tag <> 0 then
PlaceCtrl(Main.Controls[I]);
end;

Il se peut que certains ne doivent pas etre repositionnés, et comme il me faut de toute manière lire la couleur utilisée par chaque Control dans un .ini, dans le FormCreate je regle au cas par cas comme suit:

B1.Tag:=RGB(255,0,128); // sera remplacé par une lecture de Ini
PlaceCtrl(B1);

Une putain de bonne idée. Merci Florenth.
DeltaFX Messages postés 449 Date d'inscription lundi 19 avril 2004 Statut Membre Dernière intervention 8 avril 2009 2
2 janv. 2006 à 21:10
Yep, bonne idée ! :)

(En fait j'ai pas encore choppé le pli de penser que tout ce que j'ai à l'ecran est un "Control" et peut etre adressé/utilisé de cette manière.)
Vraiment bien.
Juste une suggestion: pourquoi ne pas utiliser le tag des TControl pour stocker la couleur ?
Comme cela, tu peux utiliser des procédures comme celle-cis pour tout redimentionner en une ligne:

procedure SetTLRB(const Ctrl: TControl; const Color: TColor);
var
R: TRect;
begin
if GetTLWH(Color, R) then
begin
Ctrl.Left := R.Left;
Ctrl.Top := R.Top;
Ctrl.Width := R.Right;
Ctrl.Height := R.Bottom;
end;
end;

procedure BrowseControls(const Main: TWinControl);
var
I: Integer;
begin
for I := 0 to Main.ControlCount -1 do
SetTLRB(Main.Controls[I], Main.Controls[I].Tag);
end;

Tu appelles BuildAreaColorList() puis ensuite BrowseControls(Self) et hop ! le tour est joué !

++ Flo
DeltaFX Messages postés 449 Date d'inscription lundi 19 avril 2004 Statut Membre Dernière intervention 8 avril 2009 2
31 déc. 2005 à 22:00
Addendum : Je vais devoir réécrire un bout du code car il y a une possibilité de boucle infinie, et j'aime pas.

Je vais explorer du coté des régions, histoire d'etre étanche si la tache colorée est pas parfaitement rectangulaire.

En gros à chaque ligne explorée, dès que j'ai un pixel pas blanc, je crée une region (1 pixel de haut et n de long). Si cette région à la meme couleur qu'une déja vue, je fusionne, sinon je crée une nouvelle ligne dans l'AreaColorList. Et ainsi de suite.

A la fin , GetRgnBox pour avoir le rectangle englobant de chaque région et zoooooo !

Ca sera peut-etre pas aussi rapide, mais niveau sécurité, impossible d'avoir un cercle visqueux.

Bonne Année 100000000110 :)
DeltaFX Messages postés 449 Date d'inscription lundi 19 avril 2004 Statut Membre Dernière intervention 8 avril 2009 2
30 déc. 2005 à 21:36
Ouais. Je pensais au XML au lieu d'un fichier ini.

En fait y a 2 raisons pour lesquelles j'ai fait ca :

1- Si je n'utilisais pas le compo de Mauricio je me serais dirigé vers le XML. Mais voila, vu que j'utilise un mask pour definir les boutons et que le composant de Mauricio n'affiche pas les couleur d'un masque quand elles ne sont pas référencées comme un bouton, je peux mettre mes rectangles dans ce meme masque. Le fichier de config d'un prog ne contient plus qu'une couleur, au lieux de 4 integers.

En gros tout benef pour cette utilisation particulière. Et effectivement j'ai pensé à ca pour faire du skinnable. Apres plus qu'a faire un prog pour skinner et 5 images en tout pour une form.

2- J'avais envie de faire un truc différent.
f0xi Messages postés 4205 Date d'inscription samedi 16 octobre 2004 Statut Modérateur Dernière intervention 12 mars 2022 35
30 déc. 2005 à 20:28
bravo! belle nouvelle performance.

comme tu dis, le resultat est sympa. 15ms c'est mieux que 140ms a l'origine, un gain non negligeable.

moi je considere une performance bonne quand les resultats sur un gros traitement donne a moins de 70ms.

15ms la ... c'est carrement acceptable.

sinon, pourquoi ne pas simplement utiliser une template XML ou pseudo-sctructuré-XML ?

genre :

<newzone><z>numero</z><r>left,top,width,height</r></newzone>

ou a la francis :

%numero{left,top,width,height}

ce serais moins lourd et plus simple ne pense tu pas ?


en tout cas ton truc reste interressant pour le skinning d'appli.
DeltaFX Messages postés 449 Date d'inscription lundi 19 avril 2004 Statut Membre Dernière intervention 8 avril 2009 2
29 déc. 2005 à 19:46
Testé avec un scanline (et toujours le scan d'une ligne sur 2, et d'un pixel sur 2) : gain d'un facteur 10. Exemple en 800*480 scanné en 15 millisecondes. Ca commence à être sympa.
DeltaFX Messages postés 449 Date d'inscription lundi 19 avril 2004 Statut Membre Dernière intervention 8 avril 2009 2
29 déc. 2005 à 12:55
Scanline:

Sur Y ca ne changerait rien, et déja je n'utilise qu'une ligne sur 2. Je pourrais scanner une ligne sur 3 aussi, mais dans l'identification des retctangle, ca alourdit la recherche du coin supérieur gauche du rectangle.

Sur x, mouaip, mais je devrais quand meme explorer "pixel" à "pixel" le resultat du scanline. Pour pas réexplorer chaque ligne d'un rectangle identifié, je fais un "jump" hors du rectangle, donc pas possible d'utiliser un "for" car je devrais modifier l'indice du compteur, ce qui me déplait, et donc je dois garder un while.

Mainteant si acceder au n-ieme élément du scanline me prend carrément moins de temps que de regarder le n-ieme pixel de la ligne y du bitmap, ouaip, je vais tester. :)
cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 5
28 déc. 2005 à 18:42
Le ScanLine est bien plus rapide en effet.
Par contre, le contrat est rempli même si on peut optimiser simplement en transformant le bmp en 256 couleurs, voire 16 couleurs :)

Je vais peut etre faire un update à mon compo pour implémenter cette fontion si ça interesse des personnes ...
A+
f0xi Messages postés 4205 Date d'inscription samedi 16 octobre 2004 Statut Modérateur Dernière intervention 12 mars 2022 35
28 déc. 2005 à 18:02
mmm pas mal interressant niveau recherche d'une zone de couleur dans un bitmap mais peut etre pas la meilleure solution pour disposer des elements sur une fiche.

pourquoi ne pas utiliser le ScanLine qui est plus rapide que l'utilisation de Pixel ?

en tout cas bon boulot.
DeltaFX Messages postés 449 Date d'inscription lundi 19 avril 2004 Statut Membre Dernière intervention 8 avril 2009 2
28 déc. 2005 à 12:46
Exact ! je ponds ca et j'ajoute.
cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 5
27 déc. 2005 à 18:45
Il vaudrait mieux peut-être que tu mettes un exemple ds un zip...
Rejoignez-nous