Saving all Drawn Objects into a Bitmap












1















I have a Canvass (PictureBox) and Shapes, Images or Text can be drawn on it as seen int he picture below. What I want to do now is to save them all into one BITMAP File. I have no idea so how do I start?



enter image description here



PS: I'm using different Graphics object to draw each.










share|improve this question

























  • You should use graphics object(s) that are bound to the bitmap: using(Grphics g = Graphics.FromImage(bmp)...

    – TaW
    Nov 15 '18 at 8:43













  • @TaW yeah saw that, but the project I'm working on is large now. there are a lot of graphics usage that I cannot just replace.

    – TerribleDog
    Nov 15 '18 at 9:10






  • 1





    Well I can't comment on your project but, depending on its importance I would advise to consider reafactoring it. Ideally all drawing would be in a set of functions which all take a Graphics object as a parameter and use it for drawing. This way you are free to draw onto a control surface (your canva) or a bitmap which you an display as pbox.Image or save as you like..

    – TaW
    Nov 15 '18 at 9:54
















1















I have a Canvass (PictureBox) and Shapes, Images or Text can be drawn on it as seen int he picture below. What I want to do now is to save them all into one BITMAP File. I have no idea so how do I start?



enter image description here



PS: I'm using different Graphics object to draw each.










share|improve this question

























  • You should use graphics object(s) that are bound to the bitmap: using(Grphics g = Graphics.FromImage(bmp)...

    – TaW
    Nov 15 '18 at 8:43













  • @TaW yeah saw that, but the project I'm working on is large now. there are a lot of graphics usage that I cannot just replace.

    – TerribleDog
    Nov 15 '18 at 9:10






  • 1





    Well I can't comment on your project but, depending on its importance I would advise to consider reafactoring it. Ideally all drawing would be in a set of functions which all take a Graphics object as a parameter and use it for drawing. This way you are free to draw onto a control surface (your canva) or a bitmap which you an display as pbox.Image or save as you like..

    – TaW
    Nov 15 '18 at 9:54














1












1








1








I have a Canvass (PictureBox) and Shapes, Images or Text can be drawn on it as seen int he picture below. What I want to do now is to save them all into one BITMAP File. I have no idea so how do I start?



enter image description here



PS: I'm using different Graphics object to draw each.










share|improve this question
















I have a Canvass (PictureBox) and Shapes, Images or Text can be drawn on it as seen int he picture below. What I want to do now is to save them all into one BITMAP File. I have no idea so how do I start?



enter image description here



PS: I'm using different Graphics object to draw each.







c# bitmap save picturebox






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 15 '18 at 6:50







TerribleDog

















asked Nov 15 '18 at 5:34









TerribleDogTerribleDog

46715




46715













  • You should use graphics object(s) that are bound to the bitmap: using(Grphics g = Graphics.FromImage(bmp)...

    – TaW
    Nov 15 '18 at 8:43













  • @TaW yeah saw that, but the project I'm working on is large now. there are a lot of graphics usage that I cannot just replace.

    – TerribleDog
    Nov 15 '18 at 9:10






  • 1





    Well I can't comment on your project but, depending on its importance I would advise to consider reafactoring it. Ideally all drawing would be in a set of functions which all take a Graphics object as a parameter and use it for drawing. This way you are free to draw onto a control surface (your canva) or a bitmap which you an display as pbox.Image or save as you like..

    – TaW
    Nov 15 '18 at 9:54



















  • You should use graphics object(s) that are bound to the bitmap: using(Grphics g = Graphics.FromImage(bmp)...

    – TaW
    Nov 15 '18 at 8:43













  • @TaW yeah saw that, but the project I'm working on is large now. there are a lot of graphics usage that I cannot just replace.

    – TerribleDog
    Nov 15 '18 at 9:10






  • 1





    Well I can't comment on your project but, depending on its importance I would advise to consider reafactoring it. Ideally all drawing would be in a set of functions which all take a Graphics object as a parameter and use it for drawing. This way you are free to draw onto a control surface (your canva) or a bitmap which you an display as pbox.Image or save as you like..

    – TaW
    Nov 15 '18 at 9:54

















You should use graphics object(s) that are bound to the bitmap: using(Grphics g = Graphics.FromImage(bmp)...

– TaW
Nov 15 '18 at 8:43







You should use graphics object(s) that are bound to the bitmap: using(Grphics g = Graphics.FromImage(bmp)...

– TaW
Nov 15 '18 at 8:43















@TaW yeah saw that, but the project I'm working on is large now. there are a lot of graphics usage that I cannot just replace.

– TerribleDog
Nov 15 '18 at 9:10





@TaW yeah saw that, but the project I'm working on is large now. there are a lot of graphics usage that I cannot just replace.

– TerribleDog
Nov 15 '18 at 9:10




1




1





Well I can't comment on your project but, depending on its importance I would advise to consider reafactoring it. Ideally all drawing would be in a set of functions which all take a Graphics object as a parameter and use it for drawing. This way you are free to draw onto a control surface (your canva) or a bitmap which you an display as pbox.Image or save as you like..

– TaW
Nov 15 '18 at 9:54





Well I can't comment on your project but, depending on its importance I would advise to consider reafactoring it. Ideally all drawing would be in a set of functions which all take a Graphics object as a parameter and use it for drawing. This way you are free to draw onto a control surface (your canva) or a bitmap which you an display as pbox.Image or save as you like..

– TaW
Nov 15 '18 at 9:54












2 Answers
2






active

oldest

votes


















2














Found a workaround, this will save the drawings in my pictureBox/Canvass.



private void button2_Click(object sender, EventArgs e)
{
SaveFileDialog save = new SaveFileDialog();

//Creates a filter fir saving the Project File
save.Filter = "Image Files(*.jpg; *.jpeg; *.gif; *.bmp); *.PNG|*.jpg; *.jpeg; *.gif; *.bmp; *.PNG";
save.DefaultExt = ".bmp";
save.AddExtension = true;

if (save.ShowDialog() == DialogResult.OK)
{
using (var bmp = new Bitmap(pictureBox_Canvass.Width, pictureBox_Canvass.Height))
{
pictureBox_Canvass.DrawToBitmap(bmp, new Rectangle(0, 0, bmp.Width, bmp.Height));
bmp.Save(save.FileName);
}
}
}


SAMPLE OUTPUT



enter image description here






share|improve this answer
























  • A workaround, but the correct solution is in my comment above. This solution is needlessly tying itself to the screen, which is a disadvantage. Also : If that works you are NOT using different graphics objects but only the one from the Paint event!

    – TaW
    Nov 15 '18 at 8:44













  • Please explain, how to I get the tie just the graphics in the paint event into a bitmap, just 'that' one

    – TerribleDog
    Nov 15 '18 at 9:10






  • 1





    I would create a list of a class 'DrawAction' (or if you need more flexibility an interface IDrawable) which contains all data needed to draw an item with a DrawItem(Graphics g) parameter. Then you can either loop over the items and either feed them with e.Grpahics (maybe scaled down= in the Paint event or with a bitmap-bound graphics object (maybe scaled up) when you want to create a bitmap.`

    – TaW
    Nov 15 '18 at 10:06





















1














Graphics is a "device context" object. It handles drawings on to Bitmap, but it cannot be converted back to Bitmap.



You can however copy the bits already painted on your window, and draw on to Graphics. For example:



protected override void OnMouseClick(MouseEventArgs e)
{
base.OnMouseClick(e);

//get the screen coordinates for this window
var rect = this.RectangleToScreen(this.ClientRectangle);

//copy bits from screen to bitmap
using (var bmp = new Bitmap(rect.Width, rect.Height))
{
var gr = Graphics.FromImage(bmp);
gr.CopyFromScreen(rect.Left, rect.Top, 0, 0, rect.Size);

//save to file
bmp.Save(@"c:testtest.bmp");
}
}


Or you can do this right after drawing in response to Windows messages, but you have to call Graphics::Flush to let Windows know when you have finished painting. This method assumes the target window is visible. There might be a lag between commands, or part of the window is not visible, and you don't get the desired output.



A better solution is suggested in the other answer: Create a memory bitmap and draw on to it.



If you don't want to repeat the code, you can make a function that handles all the paintings for both window's device context and memory device context:



public void do_all_paintings(Graphics gr)
{
//paint something random, add all other drawings
gr.Clear(Color.Red);
}


Now paint in response to Windows paint request:



protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
do_all_paintings(e.Graphics);
}


Use the same do_all_paintings function to create a file in response to a command:



protected override void OnMouseClick(MouseEventArgs e)
{
base.OnMouseClick(e);

var rect = this.RectangleToScreen(this.ClientRectangle);
using (var bmp = new Bitmap(rect.Width, rect.Height))
{
do_all_paintings(Graphics.FromImage(bmp));
bmp.Save(@"c:testtest.bmp");
}
}





share|improve this answer

























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53313043%2fsaving-all-drawn-objects-into-a-bitmap%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    2














    Found a workaround, this will save the drawings in my pictureBox/Canvass.



    private void button2_Click(object sender, EventArgs e)
    {
    SaveFileDialog save = new SaveFileDialog();

    //Creates a filter fir saving the Project File
    save.Filter = "Image Files(*.jpg; *.jpeg; *.gif; *.bmp); *.PNG|*.jpg; *.jpeg; *.gif; *.bmp; *.PNG";
    save.DefaultExt = ".bmp";
    save.AddExtension = true;

    if (save.ShowDialog() == DialogResult.OK)
    {
    using (var bmp = new Bitmap(pictureBox_Canvass.Width, pictureBox_Canvass.Height))
    {
    pictureBox_Canvass.DrawToBitmap(bmp, new Rectangle(0, 0, bmp.Width, bmp.Height));
    bmp.Save(save.FileName);
    }
    }
    }


    SAMPLE OUTPUT



    enter image description here






    share|improve this answer
























    • A workaround, but the correct solution is in my comment above. This solution is needlessly tying itself to the screen, which is a disadvantage. Also : If that works you are NOT using different graphics objects but only the one from the Paint event!

      – TaW
      Nov 15 '18 at 8:44













    • Please explain, how to I get the tie just the graphics in the paint event into a bitmap, just 'that' one

      – TerribleDog
      Nov 15 '18 at 9:10






    • 1





      I would create a list of a class 'DrawAction' (or if you need more flexibility an interface IDrawable) which contains all data needed to draw an item with a DrawItem(Graphics g) parameter. Then you can either loop over the items and either feed them with e.Grpahics (maybe scaled down= in the Paint event or with a bitmap-bound graphics object (maybe scaled up) when you want to create a bitmap.`

      – TaW
      Nov 15 '18 at 10:06


















    2














    Found a workaround, this will save the drawings in my pictureBox/Canvass.



    private void button2_Click(object sender, EventArgs e)
    {
    SaveFileDialog save = new SaveFileDialog();

    //Creates a filter fir saving the Project File
    save.Filter = "Image Files(*.jpg; *.jpeg; *.gif; *.bmp); *.PNG|*.jpg; *.jpeg; *.gif; *.bmp; *.PNG";
    save.DefaultExt = ".bmp";
    save.AddExtension = true;

    if (save.ShowDialog() == DialogResult.OK)
    {
    using (var bmp = new Bitmap(pictureBox_Canvass.Width, pictureBox_Canvass.Height))
    {
    pictureBox_Canvass.DrawToBitmap(bmp, new Rectangle(0, 0, bmp.Width, bmp.Height));
    bmp.Save(save.FileName);
    }
    }
    }


    SAMPLE OUTPUT



    enter image description here






    share|improve this answer
























    • A workaround, but the correct solution is in my comment above. This solution is needlessly tying itself to the screen, which is a disadvantage. Also : If that works you are NOT using different graphics objects but only the one from the Paint event!

      – TaW
      Nov 15 '18 at 8:44













    • Please explain, how to I get the tie just the graphics in the paint event into a bitmap, just 'that' one

      – TerribleDog
      Nov 15 '18 at 9:10






    • 1





      I would create a list of a class 'DrawAction' (or if you need more flexibility an interface IDrawable) which contains all data needed to draw an item with a DrawItem(Graphics g) parameter. Then you can either loop over the items and either feed them with e.Grpahics (maybe scaled down= in the Paint event or with a bitmap-bound graphics object (maybe scaled up) when you want to create a bitmap.`

      – TaW
      Nov 15 '18 at 10:06
















    2












    2








    2







    Found a workaround, this will save the drawings in my pictureBox/Canvass.



    private void button2_Click(object sender, EventArgs e)
    {
    SaveFileDialog save = new SaveFileDialog();

    //Creates a filter fir saving the Project File
    save.Filter = "Image Files(*.jpg; *.jpeg; *.gif; *.bmp); *.PNG|*.jpg; *.jpeg; *.gif; *.bmp; *.PNG";
    save.DefaultExt = ".bmp";
    save.AddExtension = true;

    if (save.ShowDialog() == DialogResult.OK)
    {
    using (var bmp = new Bitmap(pictureBox_Canvass.Width, pictureBox_Canvass.Height))
    {
    pictureBox_Canvass.DrawToBitmap(bmp, new Rectangle(0, 0, bmp.Width, bmp.Height));
    bmp.Save(save.FileName);
    }
    }
    }


    SAMPLE OUTPUT



    enter image description here






    share|improve this answer













    Found a workaround, this will save the drawings in my pictureBox/Canvass.



    private void button2_Click(object sender, EventArgs e)
    {
    SaveFileDialog save = new SaveFileDialog();

    //Creates a filter fir saving the Project File
    save.Filter = "Image Files(*.jpg; *.jpeg; *.gif; *.bmp); *.PNG|*.jpg; *.jpeg; *.gif; *.bmp; *.PNG";
    save.DefaultExt = ".bmp";
    save.AddExtension = true;

    if (save.ShowDialog() == DialogResult.OK)
    {
    using (var bmp = new Bitmap(pictureBox_Canvass.Width, pictureBox_Canvass.Height))
    {
    pictureBox_Canvass.DrawToBitmap(bmp, new Rectangle(0, 0, bmp.Width, bmp.Height));
    bmp.Save(save.FileName);
    }
    }
    }


    SAMPLE OUTPUT



    enter image description here







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 15 '18 at 7:07









    TerribleDogTerribleDog

    46715




    46715













    • A workaround, but the correct solution is in my comment above. This solution is needlessly tying itself to the screen, which is a disadvantage. Also : If that works you are NOT using different graphics objects but only the one from the Paint event!

      – TaW
      Nov 15 '18 at 8:44













    • Please explain, how to I get the tie just the graphics in the paint event into a bitmap, just 'that' one

      – TerribleDog
      Nov 15 '18 at 9:10






    • 1





      I would create a list of a class 'DrawAction' (or if you need more flexibility an interface IDrawable) which contains all data needed to draw an item with a DrawItem(Graphics g) parameter. Then you can either loop over the items and either feed them with e.Grpahics (maybe scaled down= in the Paint event or with a bitmap-bound graphics object (maybe scaled up) when you want to create a bitmap.`

      – TaW
      Nov 15 '18 at 10:06





















    • A workaround, but the correct solution is in my comment above. This solution is needlessly tying itself to the screen, which is a disadvantage. Also : If that works you are NOT using different graphics objects but only the one from the Paint event!

      – TaW
      Nov 15 '18 at 8:44













    • Please explain, how to I get the tie just the graphics in the paint event into a bitmap, just 'that' one

      – TerribleDog
      Nov 15 '18 at 9:10






    • 1





      I would create a list of a class 'DrawAction' (or if you need more flexibility an interface IDrawable) which contains all data needed to draw an item with a DrawItem(Graphics g) parameter. Then you can either loop over the items and either feed them with e.Grpahics (maybe scaled down= in the Paint event or with a bitmap-bound graphics object (maybe scaled up) when you want to create a bitmap.`

      – TaW
      Nov 15 '18 at 10:06



















    A workaround, but the correct solution is in my comment above. This solution is needlessly tying itself to the screen, which is a disadvantage. Also : If that works you are NOT using different graphics objects but only the one from the Paint event!

    – TaW
    Nov 15 '18 at 8:44







    A workaround, but the correct solution is in my comment above. This solution is needlessly tying itself to the screen, which is a disadvantage. Also : If that works you are NOT using different graphics objects but only the one from the Paint event!

    – TaW
    Nov 15 '18 at 8:44















    Please explain, how to I get the tie just the graphics in the paint event into a bitmap, just 'that' one

    – TerribleDog
    Nov 15 '18 at 9:10





    Please explain, how to I get the tie just the graphics in the paint event into a bitmap, just 'that' one

    – TerribleDog
    Nov 15 '18 at 9:10




    1




    1





    I would create a list of a class 'DrawAction' (or if you need more flexibility an interface IDrawable) which contains all data needed to draw an item with a DrawItem(Graphics g) parameter. Then you can either loop over the items and either feed them with e.Grpahics (maybe scaled down= in the Paint event or with a bitmap-bound graphics object (maybe scaled up) when you want to create a bitmap.`

    – TaW
    Nov 15 '18 at 10:06







    I would create a list of a class 'DrawAction' (or if you need more flexibility an interface IDrawable) which contains all data needed to draw an item with a DrawItem(Graphics g) parameter. Then you can either loop over the items and either feed them with e.Grpahics (maybe scaled down= in the Paint event or with a bitmap-bound graphics object (maybe scaled up) when you want to create a bitmap.`

    – TaW
    Nov 15 '18 at 10:06















    1














    Graphics is a "device context" object. It handles drawings on to Bitmap, but it cannot be converted back to Bitmap.



    You can however copy the bits already painted on your window, and draw on to Graphics. For example:



    protected override void OnMouseClick(MouseEventArgs e)
    {
    base.OnMouseClick(e);

    //get the screen coordinates for this window
    var rect = this.RectangleToScreen(this.ClientRectangle);

    //copy bits from screen to bitmap
    using (var bmp = new Bitmap(rect.Width, rect.Height))
    {
    var gr = Graphics.FromImage(bmp);
    gr.CopyFromScreen(rect.Left, rect.Top, 0, 0, rect.Size);

    //save to file
    bmp.Save(@"c:testtest.bmp");
    }
    }


    Or you can do this right after drawing in response to Windows messages, but you have to call Graphics::Flush to let Windows know when you have finished painting. This method assumes the target window is visible. There might be a lag between commands, or part of the window is not visible, and you don't get the desired output.



    A better solution is suggested in the other answer: Create a memory bitmap and draw on to it.



    If you don't want to repeat the code, you can make a function that handles all the paintings for both window's device context and memory device context:



    public void do_all_paintings(Graphics gr)
    {
    //paint something random, add all other drawings
    gr.Clear(Color.Red);
    }


    Now paint in response to Windows paint request:



    protected override void OnPaint(PaintEventArgs e)
    {
    base.OnPaint(e);
    do_all_paintings(e.Graphics);
    }


    Use the same do_all_paintings function to create a file in response to a command:



    protected override void OnMouseClick(MouseEventArgs e)
    {
    base.OnMouseClick(e);

    var rect = this.RectangleToScreen(this.ClientRectangle);
    using (var bmp = new Bitmap(rect.Width, rect.Height))
    {
    do_all_paintings(Graphics.FromImage(bmp));
    bmp.Save(@"c:testtest.bmp");
    }
    }





    share|improve this answer






























      1














      Graphics is a "device context" object. It handles drawings on to Bitmap, but it cannot be converted back to Bitmap.



      You can however copy the bits already painted on your window, and draw on to Graphics. For example:



      protected override void OnMouseClick(MouseEventArgs e)
      {
      base.OnMouseClick(e);

      //get the screen coordinates for this window
      var rect = this.RectangleToScreen(this.ClientRectangle);

      //copy bits from screen to bitmap
      using (var bmp = new Bitmap(rect.Width, rect.Height))
      {
      var gr = Graphics.FromImage(bmp);
      gr.CopyFromScreen(rect.Left, rect.Top, 0, 0, rect.Size);

      //save to file
      bmp.Save(@"c:testtest.bmp");
      }
      }


      Or you can do this right after drawing in response to Windows messages, but you have to call Graphics::Flush to let Windows know when you have finished painting. This method assumes the target window is visible. There might be a lag between commands, or part of the window is not visible, and you don't get the desired output.



      A better solution is suggested in the other answer: Create a memory bitmap and draw on to it.



      If you don't want to repeat the code, you can make a function that handles all the paintings for both window's device context and memory device context:



      public void do_all_paintings(Graphics gr)
      {
      //paint something random, add all other drawings
      gr.Clear(Color.Red);
      }


      Now paint in response to Windows paint request:



      protected override void OnPaint(PaintEventArgs e)
      {
      base.OnPaint(e);
      do_all_paintings(e.Graphics);
      }


      Use the same do_all_paintings function to create a file in response to a command:



      protected override void OnMouseClick(MouseEventArgs e)
      {
      base.OnMouseClick(e);

      var rect = this.RectangleToScreen(this.ClientRectangle);
      using (var bmp = new Bitmap(rect.Width, rect.Height))
      {
      do_all_paintings(Graphics.FromImage(bmp));
      bmp.Save(@"c:testtest.bmp");
      }
      }





      share|improve this answer




























        1












        1








        1







        Graphics is a "device context" object. It handles drawings on to Bitmap, but it cannot be converted back to Bitmap.



        You can however copy the bits already painted on your window, and draw on to Graphics. For example:



        protected override void OnMouseClick(MouseEventArgs e)
        {
        base.OnMouseClick(e);

        //get the screen coordinates for this window
        var rect = this.RectangleToScreen(this.ClientRectangle);

        //copy bits from screen to bitmap
        using (var bmp = new Bitmap(rect.Width, rect.Height))
        {
        var gr = Graphics.FromImage(bmp);
        gr.CopyFromScreen(rect.Left, rect.Top, 0, 0, rect.Size);

        //save to file
        bmp.Save(@"c:testtest.bmp");
        }
        }


        Or you can do this right after drawing in response to Windows messages, but you have to call Graphics::Flush to let Windows know when you have finished painting. This method assumes the target window is visible. There might be a lag between commands, or part of the window is not visible, and you don't get the desired output.



        A better solution is suggested in the other answer: Create a memory bitmap and draw on to it.



        If you don't want to repeat the code, you can make a function that handles all the paintings for both window's device context and memory device context:



        public void do_all_paintings(Graphics gr)
        {
        //paint something random, add all other drawings
        gr.Clear(Color.Red);
        }


        Now paint in response to Windows paint request:



        protected override void OnPaint(PaintEventArgs e)
        {
        base.OnPaint(e);
        do_all_paintings(e.Graphics);
        }


        Use the same do_all_paintings function to create a file in response to a command:



        protected override void OnMouseClick(MouseEventArgs e)
        {
        base.OnMouseClick(e);

        var rect = this.RectangleToScreen(this.ClientRectangle);
        using (var bmp = new Bitmap(rect.Width, rect.Height))
        {
        do_all_paintings(Graphics.FromImage(bmp));
        bmp.Save(@"c:testtest.bmp");
        }
        }





        share|improve this answer















        Graphics is a "device context" object. It handles drawings on to Bitmap, but it cannot be converted back to Bitmap.



        You can however copy the bits already painted on your window, and draw on to Graphics. For example:



        protected override void OnMouseClick(MouseEventArgs e)
        {
        base.OnMouseClick(e);

        //get the screen coordinates for this window
        var rect = this.RectangleToScreen(this.ClientRectangle);

        //copy bits from screen to bitmap
        using (var bmp = new Bitmap(rect.Width, rect.Height))
        {
        var gr = Graphics.FromImage(bmp);
        gr.CopyFromScreen(rect.Left, rect.Top, 0, 0, rect.Size);

        //save to file
        bmp.Save(@"c:testtest.bmp");
        }
        }


        Or you can do this right after drawing in response to Windows messages, but you have to call Graphics::Flush to let Windows know when you have finished painting. This method assumes the target window is visible. There might be a lag between commands, or part of the window is not visible, and you don't get the desired output.



        A better solution is suggested in the other answer: Create a memory bitmap and draw on to it.



        If you don't want to repeat the code, you can make a function that handles all the paintings for both window's device context and memory device context:



        public void do_all_paintings(Graphics gr)
        {
        //paint something random, add all other drawings
        gr.Clear(Color.Red);
        }


        Now paint in response to Windows paint request:



        protected override void OnPaint(PaintEventArgs e)
        {
        base.OnPaint(e);
        do_all_paintings(e.Graphics);
        }


        Use the same do_all_paintings function to create a file in response to a command:



        protected override void OnMouseClick(MouseEventArgs e)
        {
        base.OnMouseClick(e);

        var rect = this.RectangleToScreen(this.ClientRectangle);
        using (var bmp = new Bitmap(rect.Width, rect.Height))
        {
        do_all_paintings(Graphics.FromImage(bmp));
        bmp.Save(@"c:testtest.bmp");
        }
        }






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 16 '18 at 3:35

























        answered Nov 16 '18 at 3:09









        Barmak ShemiraniBarmak Shemirani

        21.6k42246




        21.6k42246






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53313043%2fsaving-all-drawn-objects-into-a-bitmap%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Florida Star v. B. J. F.

            Danny Elfman

            Lugert, Oklahoma