Image de fond picturebox

Résolu
olibara Messages postés 666 Date d'inscription dimanche 16 décembre 2007 Statut Membre Dernière intervention 11 mars 2010 - 15 févr. 2008 à 00:16
olibara Messages postés 666 Date d'inscription dimanche 16 décembre 2007 Statut Membre Dernière intervention 11 mars 2010 - 24 févr. 2008 à 19:09
Bonjour,

Je n'ai toujours pas trouvé comment exploiter correctement un picture box
Voici ce que je veux faire
1- J'ai un premier process de chargement qui construit une image dans le picturebox

      Image monImage = new Bitmap(PictureBox.Width, PictureBox.Height);
      Graphics graphics = Graphics.FromImage(monImage);


     quelques draw divers et j'obtiens mon image finale.
    
      PictureBox.Image = monImage;

A ce stade, je sors du process et mon picture box affiche une image qui doit servir de fond pour d'autre manipulations

Comment dois-je faire pour "fixer" quelque part cette image et la reutiliser comme base de fond a chaque appel de procedure qui vont temporairement modifier les objets affichés sur cette image dans le PB mais qui devront ensuite disparaitre ?

Suite a mon precédent message expliqué différement personne ne semble avoir de solution ?

Est-ce possible ?

11 réponses

Lutinore Messages postés 3246 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 27 octobre 2012 41
16 févr. 2008 à 23:49
Les dessins GDI+ ne sont pas persistants sauf si tu dessines directement sur un bitmap, c'est bien pour ça que je n'utlise pas de Refresh ni de Invalidate dans mon code.

graphics.FillEllipse( Brushes.Black, 10, 10, 100, 100 );
3
Lutinore Messages postés 3246 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 27 octobre 2012 41
15 févr. 2008 à 19:57
Salut, si tu utilises Graphics.FromImage pour dessiner sur ton bitmap les dessins seront persistants, dans ce cas fais une copie du bitmap avant ou après tes modifications. 2éme point important, dessiner sur le Graphics d'une PictureBox ça ne veut pas dire dessiner sur le Graphics de l'image contenue dans cette même PictureBox..


Un exemple :

public partial class Form1 : Form
{
    Bitmap bmp = null;


    public Form1( )
    {
        InitializeComponent( );


        bmp = this.Icon.ToBitmap( ); // pour l'exemple.


        PictureBox pb = new PictureBox( );
        pb.Parent = this;
        pb.Dock = DockStyle.Fill;
        pb.SizeMode = PictureBoxSizeMode.StretchImage;
        pb.Image = bmp;


        Button b1 = new Button( );
        b1.Parent = this;
        b1.Dock = DockStyle.Bottom;
        b1.Text = "Draw";
        b1.Click += delegate
        {
            using ( Graphics g = pb.CreateGraphics( ) )
            {
                g.DrawEllipse( new Pen( Color.Black, 10.0f ), 10, 10, 100, 100 );
            }
        };


        Button b2 = new Button( );
        b2.Parent = this;
        b2.Dock = DockStyle.Bottom;
        b2.Text = "Clear";        b2.Click +delegate { pb.Image bmp; }; // Restore le bitmap initial.  
    }
}
0
olibara Messages postés 666 Date d'inscription dimanche 16 décembre 2007 Statut Membre Dernière intervention 11 mars 2010 6
15 févr. 2008 à 20:49
Oups !

Voila quelques nouveaux concepts...
A mon avis je comprendrais mieux si je comprenais deja les concepts de base de PictureBox.Image et de Graphics.

Dans ton exemple tu cree le pb et les button "on the fly" c'est bon a connaitre mais ca n'aide pas a focaliser sur la question de base

Ce que je pense avoir déja compris.

PictureBox.backroundImage permet d'avoir une image de fond qui aura pour effet magique de s'étendre en mosaique si on resize le pb : ce n'est pas ce que je cherche

Image monImage = new Bitmap(une taille / ou un fichier / ou une autre image); Cree une instance d'image en memoire

La nuance ci apres 

Est ce que ce que tu fais
    Graphics g = pb.CreateGraphics( ) )

Est equivalent a ce que j'avais trouvé ?
    Image monImage = new Bitmap(PictureBox.Width, PictureBox.Height);
    Graphics graphics = Graphics.FromImage(monImage);
   
Actuellement je charge un premier fond sur disque
    Image monImage = new Bitmap(monfichier);

puis j'y ajoute des informations de base

          graphics.DrawEllipse(Pens.Blue, tX, tY, 2, 2);
etc.

Quelle st la bonne maniere de conserver l'imge creee pour réutilisation ?

Je pensais declarer une BaseImage dans la form
Et lorsque le draw initial est fini

     BaseImage = new Bitmap(monImage);

Ainsi je peux utiliser BaseImage partout
Mais je ne sais pas si c'est vraiment la bonne methode

J'en ai aussi besoin si je veux dessiner une segment d'origine fixe mais avec un point mobile determiné par le mouse move, j'imagine qu'a chaque move je dois reprendre l'image de fond et redessiner le segment non ?

Merce
0
Lutinore Messages postés 3246 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 27 octobre 2012 41
16 févr. 2008 à 01:46
As-tu testé mon code pour comprendre comment ça marche ?

pb.CreateGraphics( ) est différent de Graphics.FromImage( monImage ), si tu dessines sur le Graphics de la PictureBox tu ne modifies pas l'image qu'elle contient.

Tu peux faire un Clone baseImage = new Bitmap( monImage ) ou travailler sur un "back buffer" mais c'est pas forcément utile, dans mon code j'ai pas de clone et pourtant j'arrive à réinitialisé l'image dans son état original sans la recharger depuis le disque.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
olibara Messages postés 666 Date d'inscription dimanche 16 décembre 2007 Statut Membre Dernière intervention 11 mars 2010 6
16 févr. 2008 à 17:00
Bonjour,

Excuse moi mais ca reste un peu ténébreux.

Voici pratiquement ce que j'essaye de faire
1- Au form load, je charge un bmp dans le PB et je postionne des points dessus.
Ensuite l'app peut appeller 2 fonction selon le mode choisi

1 Calcul de distance entre deux points
2 Ajout de points

En mode calcul de distance a chaque click, je dessine le segment entre le point cliqué et le point précédent et j'affiche la distance actuelle et la distance cumulée
En mode ajout, je veux fais disparaitre les segments dessiné par distance et permettre l'ajout de point

Et apres j'aimerais aller plus loin en faisant un draw de segment qui suit le mousemove

J'aimerais avec cet exercice joindre l'utile et l'agreable. L'agreable etant de mieux comprendre certains fondamentaux car actuellement je demare en apprenant sur le tas en utilisant de bouts de codes que je trouve et essayant d'approfondir ma connaissance

Merci de ton aide

Voici l'essentiel de mes deux fonctions
Quelles connerie j'aurais du eviter ?

    // ********************************************************************************
    int CalcDist(Point pa)
    {
      int idx;
      TS_POINT pb;


      idx = findAddrXY(pa, 0);


      if (pRef.X 0 && pRef.Y 0)
      {
        pRef.X = pa.X;
        pRef.Y = pa.Y;
        return 0;
      }
      Graphics graphics = pb_cont.CreateGraphics(); // En m'inspirant de ton conseil mais ca ne marche pas
//     Graphics graphics = Graphics.FromImage(this.pb_cont.Image);


      graphics.DrawLine(Pens.Black, pRef, pa);
      pb_cont.Refresh();


      return 0;
   }
    // ********************************************************************************
    int AddAddr(Point pa)
    {
  
      Image cityImage;
      cityImage = new Bitmap(this.pb_cont.Image);
      Graphics graphics = Graphics.FromImage(cityImage);
      graphics.DrawEllipse(Pens.Red, pa.X, pb.Y, 2, 2);
      this.pb_cont.Image = cityImage;


      return 0;
    }  
0
olibara Messages postés 666 Date d'inscription dimanche 16 décembre 2007 Statut Membre Dernière intervention 11 mars 2010 6
16 févr. 2008 à 18:45
Salut,

ca commence a viendre !

Je viens de comprendre qu'avec le code que j'avais ecris avant, j'etais obligé de faire un refresh puisque je dessinais sur l'image du pb

     Graphics graphics = Graphics.FromImage(this.pb_cont.Image);
     graphics.DrawLine(Pens.Black, pRef, pa);
      pb_cont.Refresh();

Tandis qu'avec ta suggestion le refresh que j'avais laissé bousille on contraire ce que je viens de fair sur le graphic indépendant de l'image du pb

     Graphics graphics = pb_cont.CreateGraphics(); 
     graphics.DrawLine(Pens.Black, pRef, pa);

Mais j'ai encore du chemin a faire pour connaitre mieux tout ca
A propos comment puis-je dessiner un cercle mais plein !

DrawEllipse ne donne qu'une circonférence
0
cs_coq Messages postés 6349 Date d'inscription samedi 1 juin 2002 Statut Membre Dernière intervention 2 août 2014 101
16 févr. 2008 à 23:46
Salut,

Avec FillEllipse.

/*
coq
MVP Visual C#
CoqBlog
*/
0
Lutinore Messages postés 3246 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 27 octobre 2012 41
16 févr. 2008 à 23:50
Mince.. j't'avais pas vu Coq.
0
cs_coq Messages postés 6349 Date d'inscription samedi 1 juin 2002 Statut Membre Dernière intervention 2 août 2014 101
16 févr. 2008 à 23:54
Yes !
Comme au bon vieux temps :p

/*
coq
MVP Visual C#
CoqBlog
*/
0
olibara Messages postés 666 Date d'inscription dimanche 16 décembre 2007 Statut Membre Dernière intervention 11 mars 2010 6
17 févr. 2008 à 09:42
Merci beaucoup Lutinore
et aussi coq

J'ai avancé de deux bon pas !
0
olibara Messages postés 666 Date d'inscription dimanche 16 décembre 2007 Statut Membre Dernière intervention 11 mars 2010 6
24 févr. 2008 à 19:09
Bonsoir

Toujours dans le meme contexte :
J'essaye de faire quelque chose mais je ne sais pas si c'est possible

En fait j'essaye de faire DEUX operation dans le meme process
1- Mettre a jour l'image de fond de mon picture baox avec des nouveaux element
2- Ajouter des elements provisoire sur un layer complémentaire

Voici mon code
A la fin du process, je fais 
      this.pb_cont.Image = cityImage;
Ce qui a pour effet de sauver la nouvelle image dans pb et l'afficher
Mais aussi de zapper ce que j'ai dessiné sur mon layer intermediaire graphicsT

Est-il possible d'éviter cela ou de  reappliquer graphicsT sur l'image du PB ?

Merci de votre aide

    private void DrawCityList(DataSet cityList,SolidBrush AskBrush,int size)
    {


      cityImage = new Bitmap(this.pb_cont.Image);


      Graphics graphics = Graphics.FromImage(cityImage);
      Graphics graphicsT = pb_cont.CreateGraphics();


      foreach (AddrList cAdr in AddrLst)
      {
        graphics.DrawEllipse(Pens.Blue, cAdr.X - 1, cAdr.Y - 1, 2, 2);
        if (cAdr.active)
        {
          if (AskBrush != null)
          {
            graphicsT.FillEllipse(AskBrush, tX - size/2, tY - size/2, size, size);
          }
        }
      }


      this.pb_cont.Image = cityImage;
    }
0
Rejoignez-nous