REGION À PARTIR D'UN BITMAP

MangaII Messages postés 129 Date d'inscription dimanche 9 décembre 2001 Statut Membre Dernière intervention 12 janvier 2009 - 3 mai 2003 à 09:17
clempar55 Messages postés 59 Date d'inscription samedi 1 janvier 2005 Statut Membre Dernière intervention 4 avril 2007 - 20 avril 2006 à 11:29
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/10721-region-a-partir-d-un-bitmap

clempar55 Messages postés 59 Date d'inscription samedi 1 janvier 2005 Statut Membre Dernière intervention 4 avril 2007
20 avril 2006 à 11:29
je pense qu'il faudrait remplacer la ligne
LONG *p = (LONG *)(p32 + 4*x);

par DWORD *p = (DWORD *)(p32 + 4*x);

car sur certains processeurs un LONG ne fait pas 4 octets (je n'ai pas encore testé)
SnOOpss Messages postés 571 Date d'inscription samedi 3 avril 2004 Statut Membre Dernière intervention 5 décembre 2013
11 juin 2004 à 14:24
Salut anthrax et merci de repondre si vite je mattendais meme pas a une reponse !!!
Vla le screen shoot http://membres.lycos.fr/nsdbgt100/defo.JPG
Mais g bien fait le dialog sans bordure ni barre de titre, d'ailleur ca marche chez moi sans aucun probleme. Tandis que chez lui meme mirc meme dll( c la ou g mit ta fonction) meme theme d'ecran on a ce resultat.
La seule difference c'est ke lui a XP Gold et mo XP pro classique !!!
cs_anthraxx Messages postés 47 Date d'inscription mardi 19 mars 2002 Statut Membre Dernière intervention 9 juin 2004
11 juin 2004 à 13:44
je n'ai pas très bien compris ce qu'il se passe chez ton ami, faudrait un screenshot. Mais peut-être que ça vient du fait que ta fenêtre n'est pas sans bordure et sans barre de titre?

Sinon je peux te dire que si c'est juste un probleme de décalage je ne pense pas que ça vienne de ma fonction.
Par contre si la forme de la région obtenue n'est pas du tout la même que le dessin dans le bitmap, alors je veux bien croire qu'il y a un probleme...
SnOOpss Messages postés 571 Date d'inscription samedi 3 avril 2004 Statut Membre Dernière intervention 5 décembre 2013
10 juin 2004 à 20:34
J'ai un bug bizarre, chez moi ca marche sans probleme mais chez un ami (windows xp avec le meme theme windows que moi ). Le dialog est mal decoupé c comme si il y avait un decalge pourtant kan je blitte le bitmap apres le decoupage celui ci se met a la bonne place ( a par ke le decoupage ne ressemble a rien.
PS : en fait c dans une dll et c un aurtre programme ki cré le dialog et qui le gere !!
cs_anthraxx Messages postés 47 Date d'inscription mardi 19 mars 2002 Statut Membre Dernière intervention 9 juin 2004
31 oct. 2003 à 16:13
En effet, l'intêret du code réside dans l'optimisation des boucles.
Tu ne remarques probablement pas de différence avec ta "méthode brutale" car tu dois avoir une machine puissante.
A l'époque où j'avais fait cette fonction, j'avais essayé la méthode brutale aussi, mais elle mettait plusieurs secondes... un temps de chargement inacceptable. Aujourd'hui les ordinateurs sont plus puissants.
Je conseille quand même d'utiliser ma fonction, car même si la différence ne se voit pas, il est inutile de gacher la puissance du pc... Le jour ou tu auras installé plein de programmes qui marchent en arrière plan, qui ralentissent beaucoup, tu verras peut-être la différence.
Par contre, j'admet que mon code est beaucoup plus volumineux, donc si la taille du code est essentielle c'est toi qui choisis.

quant à la limitation du nombre de regions, je ne sais pas. Sur windows 98 il y a bien une limitation mentionnée en commentaire dans mon code, mais pour les version postérieures je ne crois pas, et en plus, la limite est de l'ordre de 2000, pas de 100.
tu devrais revoir ton code de plus près

--anthraxx
basted Messages postés 55 Date d'inscription lundi 15 septembre 2003 Statut Membre Dernière intervention 11 mai 2008
31 oct. 2003 à 12:10
tres interessante ta fonction, je n'est pas remarque de difference notable entre l'utilsation de ExtCreateRegion et CreateRgn et CombineRgm, l'interet de ton code est plutot l'optimisation des boucles, et la non utilisation de GetPxiel !!

Cf mon code:

HRGN hRgnBase = CreateRectRgn(0,0,0,0);

// algo brutale: chaque point noire arrete la delimitation d'une ligne qui devien region
for (int y=0;y<deltaYwin;y++)
for (int x=0;x<=deltaXwin;x++)
{
int x0=x;
int pos = (x+(deltaYwin-1-y)*deltaXwin)*3;
float *ptr = pixels+pos;

while (x<deltaXwin)
{
if ((ptr[0]==0)&&(ptr[1]==0)&&(ptr[2]==0)) break;
x++;
ptr+=3;
}
if (x>x0)
{
HRGN hRgnCur = CreateRectRgn(x0,y,x,y+1);
CombineRgn(hRgnBase,hRgnBase,hRgnCur,RGN_OR);
DeleteObject(hRgnCur);
}
}

J'ai cependant une question: pour un tres grand nombres de region (>100) la fenetre est bien delimité, mais le contenu de la partie basse n'est pas valide (ancienne image)

Y a t'il une limitation du nombre de region ?

Pour ma part j'utilise ce type de code pour afficher un objet 3d fait en openGL

youPiTikaée
Iwin Messages postés 24 Date d'inscription samedi 29 mars 2003 Statut Membre Dernière intervention 23 juillet 2004
29 sept. 2003 à 22:34
heu rectification, ta fonction me renvoie pas la même forme que l'image mais plutôt la forme dédoublé, j'ai réécrit une fonction qui marche bien mais qui est assez lente (elle enlève tout les pixels de la même couleur que le pixel en haut à gauche). La voila :
void AddRectToRgn( HRGN & hrgn, int left, int top, int right, int bottom )
{
if( hrgn == NULL )
hrgn = CreateRectRgn( left, top, right + 1, bottom + 1 );
else
{
HRGN hrgn2 = CreateRectRgn( left, top, right + 1, bottom + 1 );
CombineRgn( hrgn, hrgn, hrgn2, RGN_OR );
DeleteObject( hrgn2 );
}
}

HRGN BmpToRgn (HBITMAP hBmp,int xi, int yi)
{
HDC hdc = NULL;
HRGN hrgnCurrent = NULL;
hdc = CreateCompatibleDC(NULL);
SelectObject(hdc, hBmp);
COLORREF c0 = GetPixel(hdc,0,0);

for(int y=0;y<yi;y++){
for(int x=0;x<xi;x++){
if(GetPixel(hdc,x,y) != c0 ) AddRectToRgn( hrgnCurrent, x, y, x, y );
}
}
DeleteObject(hdc);
return hrgnCurrent;
}
Iwin Messages postés 24 Date d'inscription samedi 29 mars 2003 Statut Membre Dernière intervention 23 juillet 2004
12 août 2003 à 23:49
C'est vrai qu'elle est vraiment cool ta fonction, paske les CombineRgn, on peut pas en mettre plusieurs pour avoir une fenêtre composé de plus de 2 figures géométriques, alors pas mal ton truc !
cs_anthraxx Messages postés 47 Date d'inscription mardi 19 mars 2002 Statut Membre Dernière intervention 9 juin 2004
3 mai 2003 à 20:24
en reponse aux commentaires sur la vitesse d'execution:
il faut savoir que en effet la fonction utilise des instructions "for" imbriquées qui peuvent paraitre longues; cepandant, l'interieur de ces boucles n'est constitué que de code C++ et de manipulations basiques avec des pointeurs, ce qui est tres rapide, c++ etant connu pour cela.

Les autres codes sont plus lents, car s'il utilisent aussi des boucles imbriquées, celles-ci contiennent des appels aux API, comme GetPixel, CreateRectRgn et CombineRgn, et ces fonctions, elles, sont beaucoup plus lentes que des courtes operations entre pointeurs.
cs_langedechu Messages postés 20 Date d'inscription mercredi 2 avril 2003 Statut Membre Dernière intervention 12 mai 2003
3 mai 2003 à 13:34
pour resoudre le bug si utilisation de mfc :
bouton droit sur la boite de dialogue en lever l option transparent.

puis sur définir :
OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hBrush = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

switch (nCtlColor)
{

case CTLCOLOR_DLG : // pour le fond
hBrush = (HBRUSH)GetStockObject(NULL_BRUSH); // transparent
break ;

} ;
return hBrush ;

}
cs_langedechu Messages postés 20 Date d'inscription mercredi 2 avril 2003 Statut Membre Dernière intervention 12 mai 2003
3 mai 2003 à 13:16
j ai plein de bug graphique avec windows quand je fais une fenetre non carré.
par exemple si j ai une fenetre dejas ouverte ( style exploreur ou meme un autre programme ) et que je clic dessus (l ancienne fenetre)
je ma fenetre non carré qui s'efface et la partie efface reste dessiner sur l autre fenetre
cs_langedechu Messages postés 20 Date d'inscription mercredi 2 avril 2003 Statut Membre Dernière intervention 12 mai 2003
3 mai 2003 à 11:57
Super Ca marche tres bien.
Perso Ca fait un moment que je cherchais comment faire mais comme tu la dit ce que j'ai trouvé sur le net étais trops long en temps
d'execution.

Concernant le Message de MangaII : c peut etre long de passer l image poit par point au niveaux code ( en taille ) mais ca permet d avoir un temps d'execution le plus petit possible au niveau du traitement de l'image.
MangaII Messages postés 129 Date d'inscription dimanche 9 décembre 2001 Statut Membre Dernière intervention 12 janvier 2009
3 mai 2003 à 09:17
Pas mal le principe !!!
Mais le fait de passer toute l'image point par point ? c pas un peu long ?
Y'a auncune fonction de l'API qui fé ca automatiquement ?