Connecting Tech Pros Worldwide Forums | Help | Site Map

save picturebox graphics drawn by two different objects

Newbie
 
Join Date: Nov 2009
Posts: 1
#1: 4 Weeks Ago
Hi,

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

Expand|Select|Wrap|Line Numbers
  1. Pen P1;
  2. P1 = new Pen(Color.Blue, 3);
  3.  
  4. Graphics g = null;
  5. g = Graphics.FromImage(image.Image);
  6. g.DrawPath(P1, Wirepath[j-1]);
  7. P1.Dispose();
  8. g.Dispose();
In another object I used graphicspath and paint to the picturebox using onpaint

Expand|Select|Wrap|Line Numbers
  1. protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
  2. {
  3. base.OnPaint(e);
  4. if (path != null)
  5. {
  6. e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
  7. e.Graphics.FillPath(new SolidBrush(this.BackColor), path);
  8. e.Graphics.DrawPath(new Pen(this.ForeColor, 4), path);
  9. }
  10. }
I could save the graphics of the first object in picturebox image using
image.Image.Save(saveFileDialog2.FileName, ImageFormat.Jpeg);
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's Avatar
Moderator
 
Join Date: Mar 2008
Location: Arizona, USA
Posts: 1,791
#2: 4 Weeks Ago

re: save picturebox graphics drawn by two different objects


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.
tlhintoq's Avatar
Moderator
 
Join Date: Mar 2008
Location: Arizona, USA
Posts: 1,791
#3: 4 Weeks Ago

re: save picturebox graphics drawn by two different objects


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.
Newbie
 
Join Date: Nov 2009
Posts: 13
#4: 4 Weeks Ago

re: save picturebox graphics drawn by two different objects


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?
tlhintoq's Avatar
Moderator
 
Join Date: Mar 2008
Location: Arizona, USA
Posts: 1,791
#5: 4 Weeks Ago

re: save picturebox graphics drawn by two different objects


Quote:

Originally Posted by EddieT View Post

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?
Newbie
 
Join Date: Nov 2009
Posts: 13
#6: 4 Weeks Ago

re: save picturebox graphics drawn by two different objects


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.

Expand|Select|Wrap|Line Numbers
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections;
  4. using System.ComponentModel;
  5. using System.Data;
  6. using System.Drawing;
  7. using System.Drawing.Imaging;
  8. using System.Drawing.Drawing2D;
  9. using System.Windows.Forms;
  10.  
  11. namespace PowerPlanner
  12. {
  13.     public partial class PowerSysPlan : System.Windows.Forms.Form
  14.     {
  15.         public PowerSysPlan()
  16.         {
  17.             InitializeComponent();
  18.             this.SetStyle(ControlStyles.DoubleBuffer, true);
  19.             this.SetStyle(ControlStyles.UserPaint, true);
  20.             this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
  21.         }
  22.         protected override void OnPaintBackground(PaintEventArgs pevent)
  23.         {
  24.             //Don't allow the background to paint 
  25.         }
  26.  
  27.         private void ControlPaint_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
  28.         {
  29.         }
  30.         protected override void OnPaint(PaintEventArgs e)
  31.         {
  32.         }
  33.  
  34.         GraphicsPath[] Linepath = new GraphicsPath[100];
  35.         private void Drawline()
  36.         {
  37.             if ((this.pictureBox1.Width != 0) && (this.pictureBox1.Height != 0))
  38.                 this.pictureBox1.Image = new Bitmap(this.pictureBox1.Width, this.pictureBox1.Height);
  39.             Graphics.FromImage(this.pictureBox1.Image).Clear(this.BackColor);
  40.             Linepath[0] = new GraphicsPath
  41.                 (new Point[] {
  42.                                 new Point(20, 100),
  43.                                 new Point(100, 100),
  44.                                 new Point(100, 200),
  45.                                 new Point(200,200)
  46.                             },
  47.                     new byte[]  {   
  48.                                 (byte)PathPointType.Start,
  49.                                 (byte)PathPointType.Line,
  50.                                 (byte)PathPointType.Line,
  51.                                 (byte)PathPointType.Line
  52.                             });
  53.             Pen P1;
  54.             P1 = new Pen(Color.Blue, 3);
  55.  
  56.             Graphics g = null;
  57.             g = Graphics.FromImage(this.pictureBox1.Image);
  58.             g.DrawPath(P1, Linepath[0]);
  59.             P1.Dispose();
  60.             g.Dispose();
  61.         }
  62.         private void DrawText()
  63.         {
  64.             Label Labelinput = new Label();
  65.             Labelinput.ForeColor = Color.Black;
  66.             Labelinput.Location = new Point(120, 100);
  67.             Labelinput.Text = ("Text");
  68.             this.pictureBox1.Controls.Add(Labelinput);
  69.         }
  70.  
  71.         private void CreateBox()
  72.         {
  73.             ClsPart newPart = new ClsPart();
  74.             newPart.ForeColor = Color.Black;
  75.             newPart.Size = new Size(150, 50);
  76.             newPart.Type_ = ClsPart.PartType.Box;
  77.             newPart.partlabel.Text = "Box";
  78.             newPart.Name = "Box";
  79.             newPart.Location = new Point(10, 10);
  80.             this.pictureBox1.Controls.Add(newPart);
  81.         }
  82.  
  83.         private void button1_Click(object sender, EventArgs e)
  84.         {
  85.             CreateBox();
  86.             Drawline();
  87.             DrawText();
  88.         }
  89.     }
  90. }
  91.  
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.

Expand|Select|Wrap|Line Numbers
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Drawing;
  5. using System.Drawing.Drawing2D;
  6. using System.Windows.Forms;
  7. using System.Drawing.Imaging;
  8.  
  9. namespace PowerPlanner
  10. {
  11.  
  12.     public partial class ClsPart : UserControl
  13.     {
  14.         public enum PartType
  15.         {
  16.             Box,
  17.         }
  18.         private Image mypicture = null;
  19.         private PartType part = PartType.Box;
  20.         public Label partlabel = new Label();
  21.         private GraphicsPath path = null;
  22.  
  23.         int marginhorz = 5, marginvert = 5;
  24.         public ClsPart()
  25.         {
  26.         }
  27.  
  28.         public PartType Type_
  29.         {
  30.             get
  31.             {
  32.                 return part;
  33.             }
  34.             set
  35.             {
  36.                 part = value;
  37.                 mypicture = RefreshPath();
  38.                 this.Invalidate();
  39.             }
  40.         }
  41.  
  42.         // Create the corresponding GraphicsPath for the part, and apply
  43.         // it to the control by setting the Region property.
  44.         private Image RefreshPath()
  45.         {
  46.             Image canvas = new Bitmap(1000, 1000);
  47.  
  48.             path = new GraphicsPath();
  49.             partlabel.Font = new Font("Arial", 8, partlabel.Font.Style, partlabel.Font.Unit);
  50.  
  51.             path.AddRectangle(this.ClientRectangle);
  52.             partlabel.Location = new Point(marginhorz - 2, marginvert);
  53.             partlabel.Width = Convert.ToInt16(this.ClientRectangle.Width) - marginhorz * 2;
  54.             partlabel.Height = Convert.ToInt16(15);
  55.             partlabel.Name = ("Boxlabel");
  56.             this.Controls.Add(partlabel);
  57.             Graphics g = Graphics.FromImage(canvas);
  58.             Graphics.FromImage(canvas).Clear(this.BackColor);
  59.             g.SmoothingMode = SmoothingMode.AntiAlias;
  60.             g.FillPath(new SolidBrush(this.BackColor), path);
  61.             g.DrawPath(new Pen(this.ForeColor, 3), path);
  62.             g.Dispose();
  63.             this.Region = new Region(path);
  64.             return canvas;
  65.         }
  66.  
  67.         protected override void OnResize(System.EventArgs e)
  68.         {
  69.             base.OnResize(e);
  70.             mypicture = RefreshPath();
  71.             Invalidate();
  72.         }
  73.  
  74.         protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
  75.         {
  76.             base.OnPaint(e);
  77.             if (path != null)
  78.             {
  79.                 //e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
  80.                 //e.Graphics.FillPath(new SolidBrush(this.BackColor), path);
  81.                 //e.Graphics.DrawPath(new Pen(this.ForeColor, 4), path);
  82.                 e.Graphics.DrawImage(mypicture, 0, 0); //draw the image
  83.                 //mypicture.Save(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\LTP\" + Type_ + indexnumber + ".jpg", ImageFormat.Jpeg);
  84.             }
  85.         }
  86.     }
  87. }
  88.  
Attached Files
File Type: zip Testpath.zip (47.6 KB, 3 views)
tlhintoq's Avatar
Moderator
 
Join Date: Mar 2008
Location: Arizona, USA
Posts: 1,791
#7: 3 Weeks Ago

re: save picturebox graphics drawn by two different objects


Quote:
Expand|Select|Wrap|Line Numbers
  1.        protected override void OnResize(System.EventArgs e)
  2.         {
  3.             base.OnResize(e);
  4.             mypicture = RefreshPath();
  5.             Invalidate();
  6.         }
  7.  
  8.         protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
  9.         {
  10.             base.OnPaint(e);
  11.             if (path != null)
  12.             {
  13.                 //e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
  14.                 //e.Graphics.FillPath(new SolidBrush(this.BackColor), path);
  15.                 //e.Graphics.DrawPath(new Pen(this.ForeColor, 4), path);
  16.                 e.Graphics.DrawImage(mypicture, 0, 0); //draw the image
  17.                 //mypicture.Save(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\LTP\" + Type_ + indexnumber + ".jpg", ImageFormat.Jpeg);
  18.             }
  19.         }
  20.  
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.
Quote:
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.
Expand|Select|Wrap|Line Numbers
  1. myPictureBox.Image.Save(PathToSaveToAsString);
Whether or not "MyPicture" contains the same data as PictureBox1.Image... 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.
Quote:
.MyDocuments) + @"\LTP\" +
Newbie
 
Join Date: Nov 2009
Posts: 13
#8: 3 Weeks Ago

re: save picturebox graphics drawn by two different objects


Quote:
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
Expand|Select|Wrap|Line Numbers
  1.             CreateBox(); 
  2.             Drawline(); 
  3.             DrawText(); 
In the Drawline() method, you can see that I dumped the created graphics in the picturebox by
Expand|Select|Wrap|Line Numbers
  1. g = Graphics.FromImage(this.pictureBox1.Image);  
If I try to do,
Expand|Select|Wrap|Line Numbers
  1. this.pictureBox1.Image.Save(PathToSaveToAsString); 
I only see the graphics created by Drawline() method. The graphics created by CreateBox() and DrawText() do not appear.
tlhintoq's Avatar
Moderator
 
Join Date: Mar 2008
Location: Arizona, USA
Posts: 1,791
#9: 3 Weeks Ago

re: save picturebox graphics drawn by two different objects


DrawText() does not draw on the image in the picturebox. It adds a new control to the picturebox.controls list.

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

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

So when you get the image from the PIctureBox.Image, 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.Image - it is that your PictureBox.Image 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.Image as well.
Newbie
 
Join Date: Nov 2009
Posts: 13
#10: 3 Weeks Ago

re: save picturebox graphics drawn by two different objects


Thanks for your reply...
Quote:
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.Image as well.
Yes that's what I want to do - to have PictureBox.Image contain the graphics of CreateBox() and DrawText(). I know how to do for DrawLine() because I can do
Expand|Select|Wrap|Line Numbers
  1. 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?
tlhintoq's Avatar
Moderator
 
Join Date: Mar 2008
Location: Arizona, USA
Posts: 1,791
#11: 3 Weeks Ago

re: save picturebox graphics drawn by two different objects


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
Reply

Tags
image, onpaint, picturebox, save


Similar C# / C Sharp bytes