save picturebox graphics drawn by two different objects

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • eddie tan
    New Member
    • Nov 2009
    • 1

    save picturebox graphics drawn by two different objects

    Hi,

    I have a picturebox with graphics drawn from different objects. In one object I used

    Code:
    Pen P1;
    P1 = new Pen(Color.Blue, 3);
    
    Graphics g = null;
    g = Graphics.FromImage(image.Image);
    g.DrawPath(P1, Wirepath[j-1]);
    P1.Dispose();
    g.Dispose();
    In another object I used graphicspath and paint to the picturebox using onpaint

    Code:
    protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
    {
    base.OnPaint(e);
    if (path != null)
    {
    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
    e.Graphics.FillPath(new SolidBrush(this.BackColor), path);
    e.Graphics.DrawPath(new Pen(this.ForeColor, 4), path);
    }
    }
    I could save the graphics of the first object in picturebox image using
    image.Image.Sav e(saveFileDialo g2.FileName, ImageFormat.Jpe g);
    but I don't know how to combine the graphics of the first and second object. My question is how do I save the picturebox with both graphics drawn by two different objects? My first object is the main form.

    Thanks advance for any help,
    eddie
  • tlhintoq
    Recognized Expert Specialist
    • Mar 2008
    • 3532

    #2
    TIP: When you are writing your question, there is a button on the tool bar that wraps the [code] tags around your copy/pasted code. It helps a bunch. Its the button with a '#' on it. More on tags. They're cool. Check'em out.

    Comment

    • tlhintoq
      Recognized Expert Specialist
      • Mar 2008
      • 3532

      #3
      Your biggest problem is that each graphic is a flat bitmap with its own background. If you merge the two one background will completely overwrite the other.

      I suppose if the background of one is all black let's say...
      You could loop through all the pixels of it, check if it is NOT black, and copy it onto the other graphic.

      Comment

      • EddieT
        New Member
        • Nov 2009
        • 13

        #4
        But the picturebox shows the image correctly. One thing i dont understand is why can't you just grab the existing image that it's in picturebox and save it?

        Comment

        • tlhintoq
          Recognized Expert Specialist
          • Mar 2008
          • 3532

          #5
          Originally posted by EddieT
          But the picturebox shows the image correctly. One thing i dont understand is why can't you just grab the existing image that it's in picturebox and save it?
          I didn't realize that was the issue. Sorry. There is no reason you can't.
          What is your code to do so?

          Comment

          • EddieT
            New Member
            • Nov 2009
            • 13

            #6
            Below is my code in the main form which instantiates 2 objects and calling a function to draw line
            1. A label object for displaying text
            2. A drawing line function
            3. A drawing shape object (this is from Clspart class)

            I am also attaching the zip file of the entire code.

            Code:
            using System;
            using System.Collections.Generic;
            using System.Collections;
            using System.ComponentModel;
            using System.Data;
            using System.Drawing;
            using System.Drawing.Imaging;
            using System.Drawing.Drawing2D;
            using System.Windows.Forms;
            
            namespace PowerPlanner
            {
                public partial class PowerSysPlan : System.Windows.Forms.Form
                {
                    public PowerSysPlan()
                    {
                        InitializeComponent();
                        this.SetStyle(ControlStyles.DoubleBuffer, true);
                        this.SetStyle(ControlStyles.UserPaint, true);
                        this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
                    }
                    protected override void OnPaintBackground(PaintEventArgs pevent)
                    {
                        //Don't allow the background to paint 
                    }
            
                    private void ControlPaint_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
                    {
                    }
                    protected override void OnPaint(PaintEventArgs e)
                    {
                    }
            
                    GraphicsPath[] Linepath = new GraphicsPath[100];
                    private void Drawline()
                    {
                        if ((this.pictureBox1.Width != 0) && (this.pictureBox1.Height != 0))
                            this.pictureBox1.Image = new Bitmap(this.pictureBox1.Width, this.pictureBox1.Height);
                        Graphics.FromImage(this.pictureBox1.Image).Clear(this.BackColor);
                        Linepath[0] = new GraphicsPath
                            (new Point[] {
                                            new Point(20, 100),
                                            new Point(100, 100),
                                            new Point(100, 200),
                                            new Point(200,200)
                                        },
                                new byte[]  {   
                                            (byte)PathPointType.Start,
                                            (byte)PathPointType.Line,
                                            (byte)PathPointType.Line,
                                            (byte)PathPointType.Line
                                        });
                        Pen P1;
                        P1 = new Pen(Color.Blue, 3);
            
                        Graphics g = null;
                        g = Graphics.FromImage(this.pictureBox1.Image);
                        g.DrawPath(P1, Linepath[0]);
                        P1.Dispose();
                        g.Dispose();
                    }
                    private void DrawText()
                    {
                        Label Labelinput = new Label();
                        Labelinput.ForeColor = Color.Black;
                        Labelinput.Location = new Point(120, 100);
                        Labelinput.Text = ("Text");
                        this.pictureBox1.Controls.Add(Labelinput);
                    }
            
                    private void CreateBox()
                    {
                        ClsPart newPart = new ClsPart();
                        newPart.ForeColor = Color.Black;
                        newPart.Size = new Size(150, 50);
                        newPart.Type_ = ClsPart.PartType.Box;
                        newPart.partlabel.Text = "Box";
                        newPart.Name = "Box";
                        newPart.Location = new Point(10, 10);
                        this.pictureBox1.Controls.Add(newPart);
                    }
            
                    private void button1_Click(object sender, EventArgs e)
                    {
                        CreateBox();
                        Drawline();
                        DrawText();
                    }
                }
            }
            Below is the code that creates the object for drawing shapes called ClsPart. My main trouble is to have this object when drawn on the picturebox of the main form to print or save to a file. As you can see in this code, I attempted to save the image of this object into a file which works but only as a standalone object. I want to print or save the entire picture as shown in the form.

            Code:
            using System;
            using System.Collections.Generic;
            using System.ComponentModel;
            using System.Drawing;
            using System.Drawing.Drawing2D;
            using System.Windows.Forms;
            using System.Drawing.Imaging;
            
            namespace PowerPlanner
            {
            
                public partial class ClsPart : UserControl
                {
                    public enum PartType
                    {
                        Box,
                    }
                    private Image mypicture = null;
                    private PartType part = PartType.Box;
                    public Label partlabel = new Label();
                    private GraphicsPath path = null;
            
                    int marginhorz = 5, marginvert = 5;
                    public ClsPart()
                    {
                    }
            
                    public PartType Type_
                    {
                        get
                        {
                            return part;
                        }
                        set
                        {
                            part = value;
                            mypicture = RefreshPath();
                            this.Invalidate();
                        }
                    }
            
                    // Create the corresponding GraphicsPath for the part, and apply
                    // it to the control by setting the Region property.
                    private Image RefreshPath()
                    {
                        Image canvas = new Bitmap(1000, 1000);
            
                        path = new GraphicsPath();
                        partlabel.Font = new Font("Arial", 8, partlabel.Font.Style, partlabel.Font.Unit);
            
                        path.AddRectangle(this.ClientRectangle);
                        partlabel.Location = new Point(marginhorz - 2, marginvert);
                        partlabel.Width = Convert.ToInt16(this.ClientRectangle.Width) - marginhorz * 2;
                        partlabel.Height = Convert.ToInt16(15);
                        partlabel.Name = ("Boxlabel");
                        this.Controls.Add(partlabel);
                        Graphics g = Graphics.FromImage(canvas);
                        Graphics.FromImage(canvas).Clear(this.BackColor);
                        g.SmoothingMode = SmoothingMode.AntiAlias;
                        g.FillPath(new SolidBrush(this.BackColor), path);
                        g.DrawPath(new Pen(this.ForeColor, 3), path);
                        g.Dispose();
                        this.Region = new Region(path);
                        return canvas;
                    }
            
                    protected override void OnResize(System.EventArgs e)
                    {
                        base.OnResize(e);
                        mypicture = RefreshPath();
                        Invalidate();
                    }
            
                    protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
                    {
                        base.OnPaint(e);
                        if (path != null)
                        {
                            //e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
                            //e.Graphics.FillPath(new SolidBrush(this.BackColor), path);
                            //e.Graphics.DrawPath(new Pen(this.ForeColor, 4), path);
                            e.Graphics.DrawImage(mypicture, 0, 0); //draw the image
                            //mypicture.Save(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\LTP\" + Type_ + indexnumber + ".jpg", ImageFormat.Jpeg);
                        }
                    }
                }
            }
            Attached Files

            Comment

            • tlhintoq
              Recognized Expert Specialist
              • Mar 2008
              • 3532

              #7
              Code:
                     protected override void OnResize(System.EventArgs e)
                      {
                          base.OnResize(e);
                          mypicture = RefreshPath();
                          Invalidate();
                      }
               
                      protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
                      {
                          base.OnPaint(e);
                          if (path != null)
                          {
                              //e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
                              //e.Graphics.FillPath(new SolidBrush(this.BackColor), path);
                              //e.Graphics.DrawPath(new Pen(this.ForeColor, 4), path);
                              e.Graphics.DrawImage(mypicture, 0, 0); //draw the image
                              //mypicture.Save(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\LTP\" + Type_ + indexnumber + ".jpg", ImageFormat.Jpeg);
                          }
                      }
              In all of that, the only part I can find where you are trying to save is here, which doesn't look like what you described.
              One thing i dont understand is why can't you just grab the existing image that it's in picturebox and save it?
              If you want to just grab the picture box image and save, you can do that.
              Code:
              myPictureBox.Image.Save(PathToSaveToAsString);
              Whether or not "MyPicture" contains the same data as PictureBox1.Ima ge... I don't know.

              I have concerns about trying to save in the OnPaint method as this can get called very quickly and a hard drive may not be able to keep up. Drives are a lot slower than memory.

              Keep in mind that you first have to make any intermediate folders along your path before you try to save.
              .MyDocuments) + @"\LTP\" +

              Comment

              • EddieT
                New Member
                • Nov 2009
                • 13

                #8
                In all of that, the only part I can find where you are trying to save is here, which doesn't look like what you described.
                Sorry, that wasn't the place I intended to save the image. I was just testing out if I could save the image for that one object.

                What I needed is to save all the graphics created in the Form created in 3 different ways, i.e. by following functions below
                Code:
                            CreateBox(); 
                            Drawline(); 
                            DrawText();
                In the Drawline() method, you can see that I dumped the created graphics in the picturebox by
                Code:
                g = Graphics.FromImage(this.pictureBox1.Image);
                If I try to do,
                Code:
                this.pictureBox1.Image.Save(PathToSaveToAsString);
                I only see the graphics created by Drawline() method. The graphics created by CreateBox() and DrawText() do not appear.

                Comment

                • tlhintoq
                  Recognized Expert Specialist
                  • Mar 2008
                  • 3532

                  #9
                  DrawText() does not draw on the image in the picturebox. It adds a new control to the picturebox.cont rols list.

                  DrawBox() does not draw on the image in the picturebox. It adds a new control to the picturebox.cont rols list.

                  Your DrawLine() gets a graphics object from the PictureBox.Imag e and draws directly to that.

                  So when you get the image from the PIctureBox.Imag e, you only get what was drawn to the image object itself.

                  Your issues isn't that you can't save what is in the PictureBox.Imag e - it is that your PictureBox.Imag e doesn't contain what you thought it did.

                  If you want to be able to save all of that as one image, then you need to draw your box onto the image just like you did with the drawline. Same with the text: It needs to be drawn onto the PictureBox.Imag e as well.

                  Comment

                  • EddieT
                    New Member
                    • Nov 2009
                    • 13

                    #10
                    Thanks for your reply...
                    If you want to be able to save all of that as one image, then you need to draw your box onto the image just like you did with the drawline. Same with the text: It needs to be drawn onto the PictureBox.Imag e as well.
                    Yes that's what I want to do - to have PictureBox.Imag e contain the graphics of CreateBox() and DrawText(). I know how to do for DrawLine() because I can do
                    Code:
                    g = Graphics.FromImage(this.pictureBox1.Image);
                    How would you do that for DrawText() and CreateBox()?
                    DrawText() - I add text Not graphics. Do I need to convert the text to graphics? How to do that?
                    CreateBox() - This is a separate class that draws graphics, how do you transfer the graphics from this class to the Form?

                    Comment

                    • tlhintoq
                      Recognized Expert Specialist
                      • Mar 2008
                      • 3532

                      #11
                      I really suggest reading the MSDN regarding the graphics and drawing namespace. Its much easier to write the code if you read about what tools are available to you first.

                      There are methods in the framework for these.
                      DrawText article in MSDN

                      Comment

                      Working...