By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
462,363 Members | 628 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 462,363 IT Pros & Developers. It's quick & easy.

save picturebox graphics drawn by two different objects

P: 1
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
Nov 1 '09 #1
Share this Question
Share on Google+
10 Replies

tlhintoq
Expert 2.5K+
P: 3,525
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.
Nov 1 '09 #2

tlhintoq
Expert 2.5K+
P: 3,525
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.
Nov 1 '09 #3

P: 13
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?
Nov 2 '09 #4

tlhintoq
Expert 2.5K+
P: 3,525
@EddieT
I didn't realize that was the issue. Sorry. There is no reason you can't.
What is your code to do so?
Nov 2 '09 #5

P: 13
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, 196 views)
Nov 2 '09 #6

tlhintoq
Expert 2.5K+
P: 3,525
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.
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.
.MyDocuments) + @"\LTP\" +
Nov 3 '09 #7

P: 13
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.
Nov 3 '09 #8

tlhintoq
Expert 2.5K+
P: 3,525
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.
Nov 3 '09 #9

P: 13
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.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?
Nov 3 '09 #10

tlhintoq
Expert 2.5K+
P: 3,525
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
Nov 3 '09 #11

Post your reply

Sign in to post your reply or Sign up for a free account.