MorpionMx
Messages postés3466Date d'inscriptionlundi 16 octobre 2000StatutMembreDernière intervention30 octobre 2008
-
9 févr. 2005 à 10:30
MorpionMx
Messages postés3466Date d'inscriptionlundi 16 octobre 2000StatutMembreDernière intervention30 octobre 2008
-
11 févr. 2005 à 09:26
Bonjour a tous,
Voila, j'affiche dans un panel une image, que je peux resizer. Quand la longueur ou la hauteur de l'image est plus petite que celle du panel, je la raffiche au dessus et en dessous (affichage en mosaïque, quoi)
Mais le problème, c'est que parfois, ce sont des bitmap qui peuvent peser tres lourds (500 ko a 1 Mo...)
Autant vous dire que :
Plus l'image est affichée de fois, plus la taille en mémoire augmente
Plus l'image est lourde, plus l'affichage de la mosaïque est lent. (GDI+ en managé, c'est folklo )
Voici deja un bout de code :
private Image picture;
private Point pictureLocation; // Endroit ou on dessinera l'image
private Size pictureSize; // Taille de l'image
private Rectangle pictureDisplayRect; // Associe Picturelocation et Picturesize
La méthode Mosaïque est appelée par la fonction onPaint, et la méthode Zoom par le mouvement de la molette (c'est ainsi qu'on resize l'image)
Donc l'appel des méthodes se fait ainsi
Zoom -> ModifyRects -> OnPaint -> Mosaique
Comme je l'ai dit, c'est vraiment loin d'etre rapide tout ca... surtout qu'apres je drois rafficher une autre image par dessus, et du dessin...
Alors j'ai cherché plusieurs pistes.
Premierement, le code unsafe. Ca me paraissait la meilleure façon d'optimiser la chose. Cependant, je fait aucun reel "traitement" sur l'image, je l'affiche ou j'en affiche plusieurs. Donc je suis toujours dépendant de la méthode DrawImage... Les pointeurs ne peuvent pas me servir. (si ?)
Je me suis donc dit que j'allais charger l'image dans un MemoryStream, et que j'éeffectuerais a la volée le resize d'image dedans, ainsi, plus l'image serait petite, moins elle peserait, et moins ce serait lent...Que neni, a force de recreer l'image a chaque mouvement de molette, ca améliore rien du tout... loin de la !
Alors je fais appel a vous :
Auriez vous une bonne technique pour améliorer tout ca ? Comment procéderiez vous ?
Pour ce qui est de l'algorithme en mosaique, vous avez pas un exemple meilleur ? (sachant que la, ce n'est que le début, ca sert juste a remplir sur la droite et le bas, mais il faudrait aussi que je remplisse en haut et a gauche, et quand je "bouge l'image", pas seulement que je la retrecit)
cs_coq
Messages postés6349Date d'inscriptionsamedi 1 juin 2002StatutMembreDernière intervention 2 août 2014101 9 févr. 2005 à 18:47
Déjà tu devrais utiliser un buffer : par exemple tu dessines ta mosaique sur une instance de Bitmap que tu dessines en un coup après avec DrawImageUnscaled
MorpionMx
Messages postés3466Date d'inscriptionlundi 16 octobre 2000StatutMembreDernière intervention30 octobre 200857 9 févr. 2005 à 18:57
J'utilises deja un buffer (qui est le graphics g passé en parametre).
Pour le DrawImageUnscaled, je le fais lors du dessin du buffer, dans la
méthode Paint(). Par contre, si j'utilises le DrawImageUnscaled() dans
la creation de la mosaique, ca bug. (mais j'ai pas essayé de corriger,
faudrait que je vois ca)
Je me suis tourné vers l'api win32 et BitBlt. Ca améliore beaucoup les
perfs en ce qui concerne l'affichage en mosaïque. Par contre, quand il
n'y a l'image dessinée qu'une seule fois, on dirait que c'est plus lent
que le DrawImage().
Jvais encore continuer a chercher, Mes nouvelles decouvertes sont
toutes chaudes la, y'a surement moyen d'améliorer ca encore un peu.
MorpionMx
Messages postés3466Date d'inscriptionlundi 16 octobre 2000StatutMembreDernière intervention30 octobre 200857 9 févr. 2005 à 19:42
Il faut que je remplisse une forme quelconque par une image, ou plusieurs fois cette image selon sa taille.
Donc je peux déplacer l'image et la redimensionner, la contrainte
principale etant qu'il n'y ait pas de "zone blanche" dans cette forme
grace au dessin en mosaïque (ce qui n'est pas encore le cas, avec ma
fonction)
Pour info, voici ma méthode Paint
protected override void OnPaint(PaintEventArgs e)
{
if(backBuffer == null)
backBuffer = new Bitmap(this.ClientSize.Width,
this.ClientSize.Height);
La variable HighQuality etant un booleen qui est false lors du
mouseDown (Un mouseMove permet de bouger l'image, donc autant ne pas
dessiner l'image en haute qualité pendant le déplacement de celle ci).
Les images sont du type 945 x 1890 x 24 en Jpg (600 ko pour cet exemple)(j'avais dit bitmap dans mon premier post)
Si tu as d'autres astuces pour améliorer les perfs, Je suis preneur ;)
Mx
Vous n’avez pas trouvé la réponse que vous recherchez ?
MorpionMx
Messages postés3466Date d'inscriptionlundi 16 octobre 2000StatutMembreDernière intervention30 octobre 200857 11 févr. 2005 à 09:26
Si tu veux, si ca avait été pour moi, je l'aurais certainement fait en DirectX.
Mais bon, la tu vois, c'est une appli "de bureau", destiné pour un parc
de PC tres hétérogène, parfois avec des cartes graphiques peut-etre
vieilles ou désuettes.
Donc je préfère que ce type de manipulation soit traitée "softwarement".
Bitblt répond plutot a mes attentes, donc je pense que je vais l'adopter.
Je ferais une source, je pense la semaine prochaine, avec un exemple de son utilisation.
Petite question, sachant que j'utilises les fonctions la dll "gdi32.dll", est-ce que ce sera toujours géré par longhorn ?