Image GIF [Résolu]

Signaler
Messages postés
19
Date d'inscription
mercredi 18 janvier 2006
Statut
Membre
Dernière intervention
19 juin 2006
-
Messages postés
19
Date d'inscription
mercredi 18 janvier 2006
Statut
Membre
Dernière intervention
19 juin 2006
-
Bonjour, j'aimerai charger une image GIF dans un tabPage afin de dessiner des lignes dessus comme dans le Graphe réseau dugestionnaire de taches de windows.
Cependant je ne veux pas utiliser un pictureBox car j'ai pu tester avec une simple image que c'était trop lent et ca ramait fortement!!
Je voudrai savoir si vous avez une astuce ou meme un code qui permet de faire cela car j'ai beau essayer je n'y arrive pas!!
Amicalement julbuttt!
Merci davance!

8 réponses

Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
38
L'exemple simplifié avec toutes les lignes dessinées.

public partial class Form1 : Form
{
private Image image;
private Rectangle bounds;


private const int COUNT = 256;
private Random rnd = new Random( );
private Point[ ] lines = new Point[ COUNT ];
private int cnt = 0;


public Form1( )
{
InitializeComponent();
this.DoubleBuffered = true;


image = Image.FromFile( "D:\\__TMP\\image.gif" );
bounds = new Rectangle( 0, 0, image.Width, image.Height );


if ( ImageAnimator.CanAnimate( image ) )
ImageAnimator.Animate( image, OnFrameChanged );
}

// Dispose( ) { ... }


private void OnFrameChanged( object sd, EventArgs e )
{
ImageAnimator.UpdateFrames( image );
this.Invalidate( bounds ); // force Windows à appeller OnPaint.
}


protected override void OnPaint( PaintEventArgs e )
{
//base.OnPaint( e );


if ( image == null )
return;


int posX = rnd.Next( 0, bounds.Width );
int posY = rnd.Next( 0, bounds.Width );
lines[ cnt ] = new Point( posX, posY ); if ( ++cnt >COUNT ) cnt 0;

Graphics g = e.Graphics;
g.DrawImage( image, bounds ); // Dessine l'image.
g.DrawLines( Pens.Red, lines ); // Dessine les lignes par dessus l'image.

this.Text = cnt + " : " + posX + " / " + posY;
}
}
Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
38
Salut, suffit de dessiner dans l'évènement Paint du TabPage. Si c'est un gif animé utilise la classe ImageAnimator, j'avais laissé un code pour utiliser cette classe mais même Google ne le retrouve plus :( Je pourrais le réecrire si tu en as besoin.

// .NET 2.0

public Form1( ) // Constructeur de la forme.
{
InitializeComponent( );


Image image = Image.FromFile( "D:\\__TMP\\image.gif" );
Rectangle bounds = new Rectangle( 0, 0, image.Width, image.Height );
this.tabPage1.Paint += delegate( object sd, PaintEventArgs e )
{
if ( image == null )
return;


e.Graphics.DrawImage( image, bounds );
};
}
Messages postés
19
Date d'inscription
mercredi 18 janvier 2006
Statut
Membre
Dernière intervention
19 juin 2006

Salut, alors, j'ai reussi à charger mon image gif avec la classe imageAnimator, celle-ci bouge comme elle doit le faire et j'arrive a dessiner dessus, le probleme est qu'a chaque fois que l'image bouge, les lignes que j'ai dessiné s'effacent et donc je ne sais pas comment faire pour remédier a ce probleme!!
Ps: Je souhaite faire exactement comme la charge réseau du gestionnaire de périphérique!!
Merci!
Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
38
Voilà un TabPage avec un gif animé en arrière plan et un double buffer. Si tu dessine dans la méthode OnPaint tes dessins seront persistants.

public class MyTabPage : TabPage
{
private Image image;
private Rectangle bounds;


public MyTabPage( ) : base( )
{
this.DoubleBuffered = true; // En NET 1.1 voir SetStyle.


image = Image.FromFile( "D:\\__TMP\\image.gif" );
bounds = new Rectangle( 0, 0, image.Width, image.Height );


if ( ImageAnimator.CanAnimate( image ) )
ImageAnimator.Animate( image, OnFrameChanged ); // En NET 1.1 instancier le délégué.
}


protected override void Dispose( bool disposing )
{
try
{
if ( image != null )
{
if ( ImageAnimator.CanAnimate( image ) )
ImageAnimator.StopAnimate( image, OnFrameChanged ); // En NET 1.1 instancier le délégué.


image.Dispose( );
image = null;
}
}
finally
{
base.Dispose( disposing );
}
}


private void OnFrameChanged( object sd, EventArgs e )
{
ImageAnimator.UpdateFrames( image );
this.Invalidate( bounds );
}


protected override void OnPaint( PaintEventArgs e )
{
base.OnPaint( e );


if ( image == null )
return;


Graphics g = e.Graphics;
g.DrawImage( image, bounds );


// Ici les dessins par dessus le gif, exemple :
// g.DrawEllipse( Pens.Blue, bounds );
}
}


// Exemple d'utilisation


TabControl tc = new TabControl( );
tc.Dock = DockStyle.Fill;
TabPage tb1 = new TabPage( );
tb1.Text = "Page 1";
MyTabPage tb2 = new MyTabPage( );
tb2.Text = "Page 2";
tc.TabPages.AddRange( new TabPage[ ] { tb1, tb2 } );


this.Controls.Add( tc );
Messages postés
19
Date d'inscription
mercredi 18 janvier 2006
Statut
Membre
Dernière intervention
19 juin 2006

Merci beaucoup pour ton code!!D'ailleurs je l'ai utiliser mais le probleme reste le meme, les lignes s'effacent!!
Par contre, avec mon gif et le g.DrawEllipse(Pens.Blue, bounds); l'ellipse ne sefface pas meme quand le gif bouge!!
Je vais mettre mon code associé, ca sera plus simple et les erreurs font peut etre apparaitre plus facilement!!

public partial class Form1 : Form
{
private Image image;
private Rectangle bounds;
Point posX, posY;
Pen p;
public Form1()
{
InitializeComponent();
initGrapheReseau();
posX = new Point(35, 255); //X et Y point bas
posY = new Point(35, 255); //X et Y point haut
p = new Pen(Color.Red, 1);
}

private void initGrapheReseau()
{
this.DoubleBuffered = true; // En NET 1.1 voir SetStyle.

image = Properties.Resources.axes2;
bounds = new Rectangle(0, 0, image.Width, image.Height);

if (ImageAnimator.CanAnimate(image))
ImageAnimator.Animate(image, OnFrameChanged);
}
protected override void Dispose(bool disposing)
{
try
{
if (image != null)
{
if (ImageAnimator.CanAnimate(image))
ImageAnimator.StopAnimate(image, OnFrameChanged); // En NET 1.1 instancier le délégué.

image.Dispose();
image = null;
}
}
finally
{
base.Dispose(disposing);
}
}

private void OnFrameChanged(object sd, EventArgs e)
{
ImageAnimator.UpdateFrames(image);
this.Invalidate(bounds);
}

protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);

if (image == null)
return;

Graphics g = e.Graphics;
g.DrawImage(image, bounds);

// Ici les dessins par dessus le gif, exemple :
Random rnd = new Random();
int test = 0;

try
{
test = rnd.Next(-100, 100); //verticale positive ou negative
g.DrawLine(p, posX, posY);

if (posX.X >= Properties.Resources.axes2.Width)
{
initGrapheReseau();
posX.X posY.X 35;
posY.Y = posX.Y;
}
else
{
posX.X = posY.X;
posX.Y = posY.Y;
posY.X posY.X + 5;//interval entre les tracés 5
posY.Y = posY.Y - test;
}

if (posY.Y > 256)
posY.Y = 256; //correspond à 0%
else
{
if (posY.Y < 12)
posY.Y = 12;//correspond à 100%
}

}
catch (Exception error)
{
}
}
}

Voila et merci!!
Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
38
C'est normal..

A chaque fois que Windows doit redessiner la forme, par exemple si une autre forme vient de passer par dessus, il envoi à l'application le message WM_PAINT, on peut le recevoir dans la méthode WndProc mais en NET la manière la plus simple de gérer ce message et d'overrider la méthode OnPaint ou d'utiliser l'évènement Paint.

Il n'y a donc pas de dessins persistants, pour cela à chaque message WM_PAINT ( donc à chaque appelle de OnPaint ) il faut redessiner l'intégralité de ses dessins à l'écran, rien n'est gardé en mémoire.

C'est pour ça que DrawEllipse te semble persistante, elle dessine toujours la même ellipse au même endroit. ( c'est de cette persistance là dont je te parlais dans le message précédent, ).

Soit tu gardes toutes tes lignes dans un tableau et tu les dessines toutes d'un coup avec DrawLineS soit tu utilises un autre bitmap comme double buffer, tu dessines dans ce bitmap et c'est ce bitmap que tu dessines à l'écran avec DrawImage.
Messages postés
19
Date d'inscription
mercredi 18 janvier 2006
Statut
Membre
Dernière intervention
19 juin 2006

Merci beaucoup pour votre aide!! J'ai opté pour le bmp qui me semble etre le mieux, cependant, lors de l'execution du projet, a chaque fois que je trace une ligne, il ya un effet de scintillement mais les lignes ne s'effacent plus(chose positive ^^)! J'ai mis le this.doubleBuffered=true;
Je met le code associé que j'ai modifié:
public Form1()
{
InitializeComponent();


bmp = new Bitmap(Properties.Resources.axes2.Width, Properties.Resources.axes2.Height);
initGrapheReseau();
posX = new Point(35, 255); //X et Y point bas
posY = new Point(35, 255); //X et Y point haut
p = new Pen(Color.Red, 1);
timer = new System.Windows.Forms.Timer();
timer.Interval = 1000;
timer.Tick += new EventHandler(dessinerCourbe);
timer.Start();
}


protected void dessinerCourbe(object sender, EventArgs e)
{
Graphics g = Graphics.FromImage(bmp);
Random rnd = new Random();
int test = 0;

try
{
test = rnd.Next(-100, 100); //verticale positive ou negative
g.DrawLine(p, posX, posY);
Graphics h = this.CreateGraphics(); //recupere le contexte graphique
h.DrawImage(image, new Point(0, 0));
if (posX.X >= image.Width)
{
initGrapheReseau(); posX.X posY.X 35;
posY.Y = posX.Y;
}
else
{
posX.X = posY.X;
posX.Y = posY.Y; posY.X posY.X + 5;//interval entre les tracés 5
posY.Y = posY.Y - test;
}


if (posY.Y > 256)
posY.Y = 256; //correspond à 0%
else
{
if (posY.Y < 12)
posY.Y = 12;//correspond à 100%
}
}
catch (Exception error)
{
MessageBox.Show(error.ToString());
}
this.Invalidate(new Rectangle(new Point(0, 0), bmp.Size), true);
}

protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
if (image == null)
return;

Graphics g = e.Graphics;
g.DrawImage(bmp, e.ClipRectangle,e.ClipRectangle,GraphicsUnit.Pixel);
}

Merci!!
Messages postés
19
Date d'inscription
mercredi 18 janvier 2006
Statut
Membre
Dernière intervention
19 juin 2006

Merci pour ton aide et ton passé a te pencher sur mon probleme!! C'est le systeme du tableau de point qui a résolu mon probleme!!
Amicalement, julbuttt!!