How do I save a Winforms panel's drawing content to a file?

前端 未结 3 504
一向
一向 2020-12-06 23:40

I made a paint program, and the drawing content (from System.Drawing) is drawn on the panel. I attempted this method to do a simple save for now, and I only get a blank imag

相关标签:
3条回答
  • 2020-12-07 00:21

    Head over this code ScreenToGif on GitHub.

    There is an implementation in the folder GifRecorder\Controls\FreeDrawPanel.cs, it suports square and round brushes, eraser and saving the output image.

    0 讨论(0)
  • 2020-12-07 00:29

    I would skip using the panel it's not designed for graphics as much as the ImageBox is - move on to that and then you can save the contents easily.

    UPDATE PictureBox. I haven't used WinForms for a while :D

    0 讨论(0)
  • 2020-12-07 00:40

    This is a minimal doodle program which lets you draw persistent lines:

    List<Point> curPoints = new List<Point>();
    List<List<Point>> allPoints = new List<List<Point>>();
    
    private void pnlPaint_MouseDown(object sender, MouseEventArgs e)
    {
        if (curPoints.Count > 1)
        {
            // begin fresh line or curve
            curPoints.Clear();
            // startpoint
            curPoints.Add(e.Location);
        }
    }
    
    private void pnlPaint_MouseUp(object sender, MouseEventArgs e)
    {
        if (curPoints.Count > 1)
        {
            // ToList creates a copy
            allPoints.Add(curPoints.ToList());
            curPoints.Clear();
        }
    }
    
    private void pnlPaint_MouseMove(object sender, MouseEventArgs e)
    {
        if (e.Button != MouseButtons.Left) return;
        // here we should check if the distance is more than a minimum!
        curPoints.Add(e.Location);
        // let it show
        pnlPaint.Invalidate();
    }
    
    private void pnlPaint_Paint(object sender, PaintEventArgs e)
    {
        // here you can use DrawLines or DrawCurve
        // current line
        if (curPoints.Count > 1) e.Graphics.DrawCurve(Pens.Red, curPoints.ToArray());
        // other lines or curves
        foreach (List<Point> points in allPoints)
            if (points.Count > 1) e.Graphics.DrawCurve(Pens.Red, points.ToArray());
    }
    
    private void btn_undo_Click(object sender, EventArgs e)
    {
        if (allPoints.Count > 1)
        {
            allPoints.RemoveAt(allPoints.Count - 1);
            pnlPaint.Invalidate();
        }
    }
    
    private void btn_save_Click(object sender, EventArgs e)
    {
        string fileName = @"d:\test.bmp";
        Bitmap bmp = new Bitmap(pnlPaint.ClientSize.Width, pnlPaint.ClientSize.Width);
        pnlPaint.DrawToBitmap(bmp, pnlPaint.ClientRectangle);
        bmp.Save(fileName, ImageFormat.Bmp);
    }
    

    Add your save code and if you have problems just say so..

    Update: I have added two code pieces which do a save and an (unlimited) undo..

    Note 1: Make sure to use a DoubleBiffered Control: Either a PictureBox or a Label or maybe a Panel with DoubleBuffered on.

    Note 2: This doesn't support single clicks to create Points. As there is no DrawPoint anyway one would have to workaround if needed:

    • Either add an extra point 1 pixel away when upon MouseUp only one points is in the current curve;
    • or allow single paoints and add a FilleCircle to display them in the Paint event.
    0 讨论(0)
提交回复
热议问题