0

I've tried many methods including bitmap converting and etc. Here's my code. Would love it someone will explain to me how to save it and why. Thanks!

public partial class Form1 : Form
{
    Graphics G;
    Pen myPen = new Pen(Color.Black);
    Point sp = new Point(0, 0);
    Point ep = new Point(0, 0);
    int ctrl = 0;

    public Form1()
    {
        InitializeComponent();
    }

    private void panel1_Paint(object sender, PaintEventArgs e)
    {

    }

    private void panel1_MouseDown(object sender, MouseEventArgs e)
    {
        sp = e.Location;
        if(e.Button == MouseButtons.Left)
        {
            ctrl = 1;
        }
    }

    private void panel1_MouseUp(object sender, MouseEventArgs e)
    {
        ctrl = 0;
    }

    private void panel1_MouseMove(object sender, MouseEventArgs e)
    {
        if(ctrl == 1)
        {
            ep = e.Location;
            G = panel1.CreateGraphics();
            G.DrawLine(myPen, sp, ep);
        }
        sp = ep;
    }

    private void button1_Click(object sender, EventArgs e)
    {
        colorDialog1.ShowDialog();
        myPen.Color = colorDialog1.Color;
        colourBtn.BackColor = colorDialog1.Color;
    }

    private void clrBtn_Click(object sender, EventArgs e)
    {
        G.Clear(colorDialog2.Color);
    }

    private void button1_Click_1(object sender, EventArgs e)
    {
        colorDialog2.ShowDialog();
        panel1.BackColor = colorDialog2.Color;
        panel1Colourbtn.BackColor = colorDialog2.Color;

    }

    private void button1_Click_2(object sender, EventArgs e)
    {
        SaveFileDialog dlgSave = new SaveFileDialog();
        dlgSave.Title = "Save Image";
        dlgSave.Filter = "Bitmap Images (*.bmp)|*.bmp|All Files (*.*)|*.*";
        if (dlgSave.ShowDialog(this) == DialogResult.OK)
        {

            using (Bitmap bmp = new Bitmap(panel1.Width, panel1.Height))
            {
               // how do i save my drawing using savefiledialog? 
            }

        }
    }
René Vogt
  • 43,056
  • 14
  • 77
  • 99
  • How about the `Save()` method of the `Bitmap`? – Sami Kuhmonen Aug 09 '16 at 14:51
  • Your problem is not the saving but the drawing! The error start here: `G = panel1.CreateGraphics();` - Once you __draw from the paint event only__ you can use `DrawToBitmap` to create a saveable bitmap. For now you need to rewrite the drawing code! - [See here for more cooments and links about the very same issues](http://stackoverflow.com/questions/38821738/scratch-image-on-picturebox-c-sharp/38824386#38824386) – TaW Aug 09 '16 at 15:21
  • Do you mean i have to write my codes in paint event only? – Another One Aug 09 '16 at 15:42
  • CreateGraphics is a temporary drawing on the screen. It gets easily erased if you minimize the form. Always use the paint event of the control or generate a graphic object from a bitmap. – LarsTech Aug 09 '16 at 15:42
  • While working the accepted answer will not be performant nor allow undo. And a paint program ought to allow painting on all sorts of canvases. When you find time you may want to study the links I provided for better and more extensible solutions.. – TaW Aug 10 '16 at 09:22

2 Answers2

0

Try this:

panel1.DrawToBitmap(bmp, new Rectangle(0, 0, panel1.Width, panel1.Height));
bmp.Save(dlgSave.FileName);
TheCodingDamian
  • 443
  • 2
  • 12
  • I used that method earlier, but it only saved the backcolour of the panel, the drawings are not saved. – Another One Aug 09 '16 at 15:01
  • 1
    @AnotherOne It seems your "drawing" technique is wrong. You should perform the drawing (presumably triggerd by mouse actions) on a bitmap instance and use the `Paint` event of the panel to draw _the bitmap_ on the panel. Then you could simply save this bitmap instance in your save button handler. – René Vogt Aug 09 '16 at 15:03
  • Can't withdraw my upvote, but while, yes, the drawing tchnique is wrong, advising to draw into a bitmap and then that bitmap during mousemove is a bad idea performancewise! Draw on the surface in the paintevent only and then (and only then) DrawToBitmap to save will work fine. – TaW Aug 09 '16 at 15:25
  • @RenéVogt, so what am i supposed to write in the paint event? G.DrawLine or? – Another One Aug 09 '16 at 15:34
  • Thanks for your answers by the way – Another One Aug 09 '16 at 15:34
  • @AnotherOne that would actually be another question I won't answer in a comment. But when you already tried to type `G.DrawLine` in your IDE, you probably have seen that there is a `G.DrawImage` method. That's the method to draw an image (like a bitmap instance) on your panel. – René Vogt Aug 09 '16 at 15:36
  • @AnotherOne just saw you edited your question. My last comment assumed that `G` would be the `Graphics` instance for the panel. – René Vogt Aug 09 '16 at 15:38
  • sorry? i didn't edit anything. ill try G.DrawImage method. Thanks for ur answer. – Another One Aug 09 '16 at 15:42
0

After you edited your question I suggest to do the following:

  • create a Bitmap member in your Form with the same dimensions as the panel
  • create the Graphics G from that bitmap
  • in your panel1_MouseMove draw on that Graphics (effectivly drawing into the bitmp`
  • in your panel1_Paint draw that bitmap on the panel and
  • in your button1_Click_2 save that bitmap:

Code example:

public partial class Form1 : Form
{
    Bitmap bmp;
    Graphics G;
    Pen myPen = new Pen(Color.Black);
    Point sp = new Point(0, 0);
    Point ep = new Point(0, 0);
    int ctrl = 0;

    public Form1()
    {
        InitializeComponent();

        // create bitmap
        bmp = new Bitmap(panel1.Width, panel1.Height);

        // create Graphics
        G = Graphics.FromImage(bmp);
        G.Clear(Color.Black);

        // redraw panel
        panel1.Invalidate();
    }

    private void panel1_Paint(object sender, PaintEventArgs e)
    {
        // draw bitmap on panel
        if (bmp != null)
            e.Grahics.DrawImage(bmp, Point.Empty);
    }

    // shortened for clarity

    private void panel1_MouseMove(object sender, MouseEventArgs e)
    {
        if(ctrl == 1)
        {
            ep = e.Location;
            // draw onto graphics -> bmp
            G.DrawLine(myPen, sp, ep);
        }
        sp = ep;

        // redraw panel
        panel1.Invalidate();
    }

    private void button1_Click_2(object sender, EventArgs e)
    {
        SaveFileDialog dlgSave = new SaveFileDialog();
        dlgSave.Title = "Save Image";
        dlgSave.Filter = "Bitmap Images (*.bmp)|*.bmp|All Files (*.*)|*.*";
        if (dlgSave.ShowDialog(this) == DialogResult.OK)
        {
             bmp.Save(dlgSave.FileName);
        }
    }
}
René Vogt
  • 43,056
  • 14
  • 77
  • 99
  • updated two lines (null check in `panel1_Paint` and `panel1.Invalidate()` in `panel1_MouseMove`) – René Vogt Aug 09 '16 at 15:53
  • Thank you so much for taking your time to rewrite the code for me. For some reason my panel1 is black colour now. – Another One Aug 09 '16 at 15:59
  • @AnotherOne Was easier than to explain with words :) And, yes you didn't edit, maybe I didn't read correctly the first time, thought the code changed a little... – René Vogt Aug 09 '16 at 16:01
  • Never mind, i added in G.Clear(Color.White) instead of G.Clear(Color.Black) and fixed it! I can't thank you enough! thank you so so much! – Another One Aug 09 '16 at 16:05
  • sorry to disturb you again but the backcolor of panel1 is not saved together with the drawing. any fix? – Another One Aug 09 '16 at 16:24
  • @AnotherOne Of course, the panel itself is not part of the bitmap. Instead of setting the background color of the panel you need to clear the bitmap via `G.Clear(color)`, but that will erase everything you've drawn before....or you'll need some kind of transparency. You said "paint-like" program... afaik there is no background in paint, too. You can only paint black the whole picture :) – René Vogt Aug 09 '16 at 16:37