Image de fond picturebox [Résolu]

olibara 670 Messages postés dimanche 16 décembre 2007Date d'inscription 11 mars 2010 Dernière intervention - 15 févr. 2008 à 00:16 - Dernière réponse : olibara 670 Messages postés dimanche 16 décembre 2007Date d'inscription 11 mars 2010 Dernière intervention
- 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 ?
Afficher la suite 

Votre réponse

11 réponses

Meilleure réponse
Lutinore 3248 Messages postés lundi 25 avril 2005Date d'inscription 27 octobre 2012 Dernière intervention - 16 févr. 2008 à 23:49
3
Merci
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 );

Merci Lutinore 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 92 internautes ce mois-ci

Commenter la réponse de Lutinore
Lutinore 3248 Messages postés lundi 25 avril 2005Date d'inscription 27 octobre 2012 Dernière intervention - 15 févr. 2008 à 19:57
0
Merci
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.  
    }
}
Commenter la réponse de Lutinore
olibara 670 Messages postés dimanche 16 décembre 2007Date d'inscription 11 mars 2010 Dernière intervention - 15 févr. 2008 à 20:49
0
Merci
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
Commenter la réponse de olibara
Lutinore 3248 Messages postés lundi 25 avril 2005Date d'inscription 27 octobre 2012 Dernière intervention - 16 févr. 2008 à 01:46
0
Merci
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.
Commenter la réponse de Lutinore
olibara 670 Messages postés dimanche 16 décembre 2007Date d'inscription 11 mars 2010 Dernière intervention - 16 févr. 2008 à 17:00
0
Merci
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;
    }  
Commenter la réponse de olibara
olibara 670 Messages postés dimanche 16 décembre 2007Date d'inscription 11 mars 2010 Dernière intervention - 16 févr. 2008 à 18:45
0
Merci
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
Commenter la réponse de olibara
cs_coq 6366 Messages postés samedi 1 juin 2002Date d'inscription 2 août 2014 Dernière intervention - 16 févr. 2008 à 23:46
0
Merci
Salut,

Avec FillEllipse.

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

/*
coq
MVP Visual C#
CoqBlog
*/
Commenter la réponse de cs_coq
olibara 670 Messages postés dimanche 16 décembre 2007Date d'inscription 11 mars 2010 Dernière intervention - 17 févr. 2008 à 09:42
0
Merci
Merci beaucoup Lutinore
et aussi coq

J'ai avancé de deux bon pas !
Commenter la réponse de olibara
olibara 670 Messages postés dimanche 16 décembre 2007Date d'inscription 11 mars 2010 Dernière intervention - 24 févr. 2008 à 19:09
0
Merci
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;
    }
Commenter la réponse de olibara

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.