Hey guys,

I have a panel in C#, where the user can draw stuff, like in Paint. So, it has graphics drawn in it by the user.

How can I save the graphics as a .png, .bmp or even .jpg?

I tried a few codes that worked and created the image but it was just a white rectangle:


Code:
int width = panel1.Width;
                int height = panel1.Height;

                Bitmap bitMap = new Bitmap(width, height);
                Rectangle rec = new Rectangle(0, 0, width, height);

                panel1.DrawToBitmap(bitMap, rec);

                bitMap.Save(saveFileDialog.FileName);
I canz has full code? I can help if I could see the WHOLE thing.
http://pastebin.com/rEujwsBn

Very Happy
Bitmap.Save saves a PNG unless you explicitly pass an ImageFormat.

If you create an instance of something that implements IDisposable, you should Dispose it when done.

For example, instead of

Code:
Graphics g = panel1.CreateGraphics();
g.FillEllipse(color, e.X, e.Y, Convert.ToInt32(numericUpDown1.Value), Convert.ToInt32(numericUpDown1.Value));

use

Code:
using (Graphics g = panel1.CreateGraphics()) {
    g.FillEllipse(color, e.X, e.Y, Convert.ToInt32(numericUpDown1.Value), Convert.ToInt32(numericUpDown1.Value));
}

The same applies to Brushes, ColorDialogs, SaveFileDialogs and Bitmaps.

Code:
using (IDisposable x) {
    /* ... */
}

is essentially the same as

Code:
IDisposable x;
try {
    /* ... */
} finally {
    x.Dispose();
}


Unfortunately, there is no way to reliably save what you're currently drawing. When you create a Graphics instance and draw to the Panel you're just drawing over the top of it (and not storing those results in a buffer); if you drag the window off the screen then back on again you'll see that your drawing gets erased as the Panel repaints itself (it has no recollection of your drawing operations).

An easy way to remedy this is to draw to a Bitmap directly and then set this Bitmap to be the background of your Panel. That is,


Code:
// These are members of the Form
Bitmap drawingSurface;
Graphics drawingGraphics;

public Form1() {
    /* ... */
    this.drawingSurface = new Bitmap(400, 300);
    this.drawingGraphics = Graphics.FromImage(this.drawingSurface);
    this.panel1.BackgroundImage = this.drawingSurface;
    this.panel1.BackgroundImageLayout = ImageLayout.None; // Tile by default.
}


Now, when it comes to drawing, use the drawingGraphics, then Invalidate the panel1 to force it to redraw itself with your new background:


Code:
this.drawingGraphics.DrawLine(Pens.Black, 0, 0, 100, 100);
this.panel1.Invalidate();


(Further hint: take a look at the Graphics.SmoothingMode property to improve the appearance of shapes).

Edit: Also, NumericUpDown.Value is just a decimal, so feel free to cast it to (int) the usual way rather than go through Convert.ToInt32().

Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;


namespace mePaint
{
    public partial class Form1 : Form
    {
        bool paint = false;

        SolidBrush color;

        bool fillActivated = false;
        bool ellipseActivated = true;
        bool rectangleActivated = false;

        bool colorDialogHasBeenUsed = false;

        Color colorSet = Color.Black;

        public Form1()
        {
            InitializeComponent();
            this.WindowState = FormWindowState.Maximized;
            color = new SolidBrush(Color.Black);
            this.button3.Image = new Bitmap(button2.Image);
        }
        private void panel1_MouseUp(object sender, MouseEventArgs e)
        {
            paint = false;
            if (colorDialogHasBeenUsed)
            {
                color = new SolidBrush(colorSet);
            }
            else
            {
                color = new SolidBrush(Color.Black);
            }
        }

        private void panel1_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                color = new SolidBrush(Color.White);
            }
            if (paint)
            {
                if (ellipseActivated)
                {
                    using (Graphics g = panel1.CreateGraphics())
                    {
                        g.FillEllipse(color, e.X, e.Y, Convert.ToInt32(numericUpDown1.Value), Convert.ToInt32(numericUpDown1.Value));
                    }
                }
                else if (rectangleActivated)
                {
                    using (Graphics g = panel1.CreateGraphics())
                    {
                        g.FillRectangle(color, e.X, e.Y, Convert.ToInt32(numericUpDown1.Value), Convert.ToInt32(numericUpDown1.Value));
                    }
                }
            }
        }

        private void panel1_MouseDown(object sender, MouseEventArgs e)
        {
            paint = true;
            if (fillActivated)
                {
                    using (Graphics g = panel1.CreateGraphics())
                    {
                        g.FillRectangle(color, 0, 0, this.panel1.Width,this.panel1.Height);
                    }
                }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            ColorDialog colorDlg = new ColorDialog();
            colorDlg.AllowFullOpen = true; ;
            colorDlg.AnyColor = true;
            colorDlg.SolidColorOnly = false;

            if (colorDlg.ShowDialog() == DialogResult.OK)
            {
                color = new SolidBrush(colorDlg.Color);
                colorDialogHasBeenUsed = true;
                colorSet = colorDlg.Color;
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (ellipseActivated)
            {
                ellipseActivated = false;
                this.button3.Image = new Bitmap(button4.Image);
            }
            else
            {
                ellipseActivated = true;
                this.button3.Image = new Bitmap(button2.Image);
                fillActivated = false;
                rectangleActivated = false;
            }
        }

        private void newToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Form1 form1 = new Form1();
            form1.Show();
        }

        private void clearToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            using (Graphics g = panel1.CreateGraphics())
            {
                g.Clear(panel1.BackColor);
            }
        }

        private void button5_Click(object sender, EventArgs e)
        {
            if (rectangleActivated)
            {
                rectangleActivated = false;
                this.button3.Image = new Bitmap(button4.Image);
            }
            else
            {
                rectangleActivated = true;
                this.button3.Image = new Bitmap(button5.Image);
                fillActivated = false;
                ellipseActivated = false;
            }
        }

        private void paintAreaSizeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DefinePanelSize panelForm = new DefinePanelSize();
            panelForm.ShowDialog();
        }

        private void button6_Click(object sender, EventArgs e)
        {
            if (fillActivated)
            {
                fillActivated = false;
                this.button3.Image = new Bitmap(button4.Image);
            }
            else
            {
                fillActivated = true;
                this.button3.Image = new Bitmap(button6.Image);
                rectangleActivated = false;
                ellipseActivated = false;
            }
        }

        private void closeToolStripMenuItem_Click_1(object sender, EventArgs e)
        {
            this.Close();
        }

        private void saveToolStripMenuItem_Click_1(object sender, EventArgs e)
        {
            SaveFileDialog saveFileDialog = new SaveFileDialog();

            saveFileDialog.DefaultExt = "bmp";
            saveFileDialog.Filter = "Bitmap files|*.bmp";
            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                int width = panel1.Width;
                int height = panel1.Height;

                Bitmap bitMap = new Bitmap(width, height);
                Rectangle rec = new Rectangle(0, 0, width, height);

                panel1.DrawToBitmap(bitMap, rec);

                bitMap.Save(saveFileDialog.FileName);
            }
        }
    }
}


benryves, that was awesome, but as I was trying to implement that I got a problem, so I can't go much further, everytime I minimize the program, panel1 graphics are deleted :O

Any idea?
The answer is in the post above yours - read from the words "Unfortunately, there is no way to reliably save what you're currently drawing." (before the two lower source code boxes).
benryves wrote:
The answer is in the post above yours - read from the words "Unfortunately, there is no way to reliably save what you're currently drawing." (before the two lower source code boxes).
Exactly this. Ben gave you a very detailed post, be sure to read the whole thing carefully. Smile
Which I did. However, I am now using a pictureBox.

I can already Open and Save files, just no drawing tool yet.
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 1
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement