CLASSE DE DESSIN (API) PLUS RAPIDE QUE VB

cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 - 18 juil. 2005 à 20:46
hugoclavet Messages postés 10 Date d'inscription vendredi 5 novembre 2004 Statut Membre Dernière intervention 1 mars 2008 - 21 nov. 2005 à 17:19
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/32773-classe-de-dessin-api-plus-rapide-que-vb

hugoclavet Messages postés 10 Date d'inscription vendredi 5 novembre 2004 Statut Membre Dernière intervention 1 mars 2008
21 nov. 2005 à 17:19
J'ai trouvé un wrapper complet vb6 pour la dll gdi+

http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=42861&lngWId=1

Hugo
cs_Stephane Messages postés 550 Date d'inscription vendredi 5 janvier 2001 Statut Membre Dernière intervention 23 septembre 2006
23 juil. 2005 à 14:12
ca y est j'ai revue les deleteobject
et apres une minute de redimensionnement intense (lol) le processus (avec la fenetre a taille égale) occupait exactement la meme quantité de mémoire.
cs_Stephane Messages postés 550 Date d'inscription vendredi 5 janvier 2001 Statut Membre Dernière intervention 23 septembre 2006
21 juil. 2005 à 04:57
ok, je ferai les modifications
merci pour les infos
++
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
20 juil. 2005 à 23:36
Salut,

comme te le dit DARKSIDIOUS, tu dois absolument libérer la mémoire par DeleteObject sinon ton prog va saturer, ralentir Windows et enfin se faire expulser par Windows.
SelectObject ne fait que placer l'objet GDI spécifié en lieu et place de l'ancien, il n'a pas à libérer la mémoire, on peut très bien avoir à utiliser plus tard l'ancien objet. La libération mémoire est toujours la responsabilité du développeur.

Bonne continuation.
cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
20 juil. 2005 à 22:42
Ben écoute, j'avais fait un ocx qui utilisais environ 100 objets graphiques (pinceaux et brosses surtout), et je ne supprimais pas les anciens objets utilisés, et à chaque raffraichissement du contrôle, je perdais environ 4 Ko de mémoire. Ce n'est pas énorme tu me diras, mais ca suffisait à faire saturer la mémoire graphique (4000 objets graphiques environ) en quelques minutes seulement !).

Et là, le problème est le même pour ta source : tu perds environ 8 à 12 Ko pour chaque redimensionnement de la feuille (ce qui oblige de tout retracer), et environ 10 objets graphiques à chaque fois ! (pour t'en rendre compte, utilise le gestionnaire de processus de Windows, et affiche la colonne "Objets GDI", tu verra vite !

En théorie, lorsque tu fait un SelectObject, Windows est censé libérer les ressources de l'ancien objet graphique, mais il ne le fait pas malheureusement, et du coup, on arrive très vite à la limite des objets graphiques d'un processus !

DarK Sidious
cs_Stephane Messages postés 550 Date d'inscription vendredi 5 janvier 2001 Statut Membre Dernière intervention 23 septembre 2006
20 juil. 2005 à 22:14
ok merci pour les infos

mais les objets, je les supprime ! il y sont les deleteobject a la fin des procedures, et j'ai samurize avec l'utilisation RAM sur le bureau, j'ai redimensionné la fenetre pendant un moment, la ram ne bouge pas :)

quand tu dit :
lOldPen = SelectObject(lHdc, lPen)
DeleteObject lOldPen

j'ai vu sur la msdn que le oldpen est automatiquement remplacé par le new, tu est sur qu'il faut le supprimer aussi ?

merci a+
cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
20 juil. 2005 à 11:43
Oui ta classe évite les clignotements, et surtout, bouffe sûrement moins de mémoire que l'autoredraw ! Cependant, j'aimerais porter ton attention sur un point qui s'avère très gênant lorsqu'on utilise les api : lorsqu'on crée un crayon ou un pinceau, ca bouffe de la mémoire si on oublie de supprimer l'ancien crayon/pinceau.

Pour t'en rendre compte, lance ton prog, et redimensionne ta fenêtre un bon millier de fois tout en scruptant la consommation mémoire de celui-ci. Tu va voir qu'elle grimpe jusqu'au point de planter ton prog, à cause d'une saturation mémoire graphique !

Le nombre d'objet GDI est limité pour un prog (environ 4000 il me semble par processus), du coup, à chaque fois que tu trace une ligne ou un rectangle, et que tu ne supprime pas les anciens cratons/pinceaux, ca bouffe un objet graphique ! A force, ca sature la mémoire (j'en ai fait les frais pour un gros ocx que je développais, et qui plantait au bout de quelques minutes d'utilisation !).

Donc un conseil, lorsque tu fait :
SelectObject(lHdc, lPen)

remplace par :
lOldPen = SelectObject(lHdc, lPen)
DeleteObject lOldPen

Ca évite d'encombrer la mémoire inutilement.

Pour le tableau de bits, je peux t'assurer que VB peut le manier, reste à ne pas dépasser les limites du tableau !
Ma classe le gère très bien, par contre, elle ne gère pas le redimensionnement, c'est vrai !

On trouve pas mal de classe Handler sur le net (vbaccelerator pour ne citer que lui) surtout sur les sites de prog VB avancé.

GDI+ n'est pas inclut par défaut dans Windows 98/2000, mais il me semble que oui sous XP. La GDI+ permet surtout de gérer le 32 bits, et a une approche orientée objet comparée à la GDI32. Tu pourras trouver pas mal de doc sur le net (ami google)

Par exemple :
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdicpp/GDIPlus/GDIPlus.asp
http://www.3ie.org/nouvelles_technologies/fiches.php?techno_id=350

DarK Sidious
cs_Stephane Messages postés 550 Date d'inscription vendredi 5 janvier 2001 Statut Membre Dernière intervention 23 septembre 2006
20 juil. 2005 à 10:33
slu

merci pour ces remarques, en fait au début, j'utilisait aussi un tableau de bytes en parralele, mais j'ai eu beaucoup de problemes (crash VB) sans vraiment comprendre d'ou ca venaient (pendant les redimensionnements), puis je pense que VB n'est pas le plus adapté pour faire ce type de traitement : le redimensionnement du tableau de bytes lorsque je redimensionnai l'image, "sacadait" VB et la fenetre que j'étais en train de redimensionner.

pour la rapidité, je n'ai pas testé avec beaucoup d'opérations, mais l'avantage ici c'est que on a pas besoin de tout redessiner lors d'un message PAINT, puisque c'est juste un bitblt vers la destination, donc on gagne en vitesse, et il n'y a pas tout les clignotements.
Si la surface en question est en autoredraw=true, il n'y a pas les clignotements mais c'est beaucoup plus lent à tracer.
Cette classe est un compromis entre les deux problemes (autoredraw = false : clignotements autoredraw=true : lenteur)

Evidemment il reste à l'améliorer...

"Ca reste qu'une classe handler comme on peux en trouver de nombreuses sur internet,"
dsl j'en ai jamais vu lol

"et quitte à en faire une, ca aurait été mieux d'en faire une pour la GDI+ et non la GDI32."
GDI+ est inclu dans windows ? quels sont les avantages ? ou trouver la doc (msdn) ?

++
cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
19 juil. 2005 à 14:04
Alors, après avoir regardé de plus près ta source, voici mes remarques :

* Ta classe n'est qu'un handler des fonctions de l'API Windows "Classiques". Elle est donc plus rapide que les fonctions de VB, mais elle pourrait être bien plus rapide encore en utilisant un tableau de bits (voir ma source de gestion d'image).

* Tes fonctions d'extractions des composantes de couleurs pourrait être plus rapide en utilisant des opérations binaires au lieu des modulo !

* Tu pourrais rajouter, pour ta fonction DrawText, le type de formatage du texte et l'afficher avec la fonction de l'API DrawText, ce qui rendrait ta fonction plus intéressante.

Voilà c'est à peu près tout.

Ne le prends pas mal (ce ne sont que des remarques, et non des reproches) : ta classe est intéressante, mais n'apporte pas grand chose : tout ce que tu as fait n'est finalement que rendre l'utilisation des API Graphiques un peu plus simple, mais ca n'accèlére pas énormément le tracé des graphiques malheureusement. Ca reste qu'une classe handler comme on peux en trouver de nombreuses sur internet, et quitte à en faire une, ca aurait été mieux d'en faire une pour la GDI+ et non la GDI32.

Sinon, pour la transparence, je voulais dire : lorsque tu trace un rectangle par exemple, tracer chaque point un à un en définissant la couleur de chaque pixel selon la couleur précédente, la couleur à appliquer, et le paramètre de transparence. Mais je croyais que tu utilisais un tableau de bits, ce qui aurait été plus simple à appliquer, mais là, ca ralentirait trop le tracé !

DarK Sidious
cs_Stephane Messages postés 550 Date d'inscription vendredi 5 janvier 2001 Statut Membre Dernière intervention 23 septembre 2006
18 juil. 2005 à 20:53
hum je ne vois pas du tout comment m'y prendre pour la transparence lol, mais je retiens l'idée.
;)

++
cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
18 juil. 2005 à 20:46
Ce qui pourrait faire un plus, c'est de gérer la transparence !

Sinon, c'est bien, ca ressemble à ma classe de gestion d'image, mais tu pousse le concept plus loin en traçant des lignes et des rectangles.

Continue comme cà !

DarK Sidious
Rejoignez-nous