Search code examples
c#winformsbitmapsavebmp

How to save Panel as BMP


I am trying to save the image on my panel to a BMP and whenever it saves, there is just a blank image.

Drawing Code

    private void DrawingPanel_MouseMove(object sender, MouseEventArgs e)
    {
        OldPoint = NewPoint;
        NewPoint = new Point(e.X, e.Y);

        if (e.Button == MouseButtons.Left)
        {
            Brush brush = new SolidBrush(Color.Red);
            Pen pen = new Pen(brush, 1);

            DrawingPanel.CreateGraphics().DrawLine(pen, OldPoint, NewPoint);
        }
    }

Saving Code

    void SaveBMP(string location)
    {
        Bitmap bmp = new Bitmap((int)DrawingPanel.Width, (int)DrawingPanel.Height);
        DrawingPanel.DrawToBitmap(bmp, new Rectangle(0, 0, DrawingPanel.Width, DrawingPanel.Height));

        FileStream saveStream = new FileStream(location + ".bmp", FileMode.OpenOrCreate);
        bmp.Save(saveStream, ImageFormat.Bmp);

        saveStream.Flush();
        saveStream.Close();
    }

Final Result

This is what I drew

What I drew

This is what saves

What is saved


Solution

  • You'll have to change your code so that it overrides the OnPaint method. This is the default pattern followed when customizing the look of controls.

    The reason for why your particular code doesn't work is that DrawToBitmap must surely redraw the whole control when called. In this case, the method has no knowledge of your custom drawings to the control.

    Here is a working example:

    public partial class DrawingPanel : Panel
    {
        private List<Point> drawnPoints;
    
        public DrawingPanel()
        {
            InitializeComponent();
            drawnPoints = new List<Point>();
    
            // Double buffering is needed for drawing this smoothly,
            // else we'll experience flickering
            // since we call invalidate for the whole control.
            this.DoubleBuffered = true; 
        }
    
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
    
            // NOTE: You would want to optimize the object allocations, 
            // e.g. creating the brush and pen in the constructor
            using (Brush brush = new SolidBrush(Color.Red))
            {
                using (Pen pen = new Pen(brush, 1))
                {
                    // Redraw the stuff:
                    for (int i = 1; i < drawnPoints.Count; i++)
                    {
                        e.Graphics.DrawLine(pen, drawnPoints[i - 1], drawnPoints[i]);
                    }
                }
            }
        }
    
        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);
    
            // Just saving the painted data here:
            if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                drawnPoints.Add(e.Location);
                this.Invalidate();
            }
        }
    
        public void SaveBitmap(string location)
        {
            Bitmap bmp = new Bitmap((int)Width, (int)Height);
            DrawToBitmap(bmp, new Rectangle(0, 0, Width, Height));
    
            using (FileStream saveStream = new FileStream(location + ".bmp", FileMode.OpenOrCreate))
            {
                bmp.Save(saveStream, ImageFormat.Bmp);
            }                       
        }
    }