Re: Saving and loading bmp using graphics object

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance

From: Ian Griffiths [C# MVP] (ian-interact-sw_at_nospam.nospam)
Date: 11/24/04


Date: Wed, 24 Nov 2004 08:27:44 -0000

Windows needs to know that part of your window needs redrawing. Remember
that you're now drawing into an off-screen bitmap, and Windows doesn't know
that this bitmap is a copy of what you want to appear on screen. (Windows
has no intrinsic support for this idea of a window with some bitmap backing
store, so it just plain doesn't understand the idea that a bitmap might be
associated with what's on screen.)

So you need to tell Windows. The way to do this is to call the Invalidate
method on your control. You could just call it with no parameters - that
will refresh the whole control. However, that can be a little slow - a more
efficient way of doing it would be to call the one that takes a rectangle,
telling it which part just changed. When you do either of these, your
OnPaint method will get called, allowing the results to appear on screen.

So here's the simple but slow version:

 private void DrawPoint(int x, int y)
 {
   using (objGraphics = Graphics.FromImage(objBitmap))
  {
    objGraphics.DrawLine(APen, x, y, OldX, OldY);
  }

  Invalidate();
}

I'll leave it as an exercise to work out the faster version. ;-)

Also, you're going to have to think about what you want to do when the
window is resized. Resizing the bitmap is one option, but to do that you'd
have to build a new one, and then draw the existing one into the new one.
Or you could just pick a bitmap size up front and not resize it. (So think
about what Windows PaintBrush does. It doesn't keep resizing the bitmap
every time you resize the window. The bitmap size remains the same until
you change it.)

-- 
Ian Griffiths - http://www.interact-sw.co.uk/iangblog/
DevelopMentor - http://www.develop.com/
"Vin" wrote:
> Thanks Ian, you've been of great help.
> I did what you suggested and it seems to work. But I got couple of
> problems.
>
> 1> I can't see my lines being drawn on mousemove. When I move the
> window, resize it the drawing gets shown. but no on mouse move.
>
> 2> When I save the bitmap, the bmp file is black, where as my form
> suface is white. No clue what's going wrong here.
>
> Here's my code.
>
> Kindly point me where am I making a mistake.
>
> private Pen APen;
> private int OldX;
> private int OldY;
>
> private void DrawPoint(int x, int y)
> {
> using (objGraphics  = Graphics.FromImage(objBitmap))
> {
> objGraphics.DrawLine(APen, x, y, OldX, OldY);
> }
> }
>
> protected override void OnPaint(PaintEventArgs e)
> {
> e.Graphics.DrawImage(objBitmap, 0, 0);
> base.OnPaint(e);
> }
>
> private void ResetOffset(int x, int y)
> {
> ResetOffset(x, y, false);
> }
>
> private void ResetOffset(int x, int y, bool Reset)
> {
> OldX = x + System.Convert.ToInt32(Reset);
> OldY = y + System.Convert.ToInt32(Reset);
> }
>
> private void Scribbler_MouseMove(object sender,
> System.Windows.Forms.MouseEventArgs e)
> {
> StatusBar1.Text = string.Format("X:{0:d},Y:{0:d}", e.X, e.Y);
> if ((e.Button == MouseButtons.Left))
> {
>
> DrawPoint(e.X, e.Y);
> }
> ResetOffset(e.X, e.Y, e.Button == MouseButtons.None);
> }
>
> private void Scribbler_MouseDown(object sender,
> System.Windows.Forms.MouseEventArgs e)
> {
> DrawPoint(e.X, e.Y);
> }
>
> private void Button1_Click(object sender, System.EventArgs e)
> {
> APen = new Pen(Color.Red);
> }
>
> private void Button2_Click(object sender, System.EventArgs e)
> {
> APen = new Pen(Color.Blue);
> }
>
> private void Button3_Click(object sender, System.EventArgs e)
> {
> APen = new Pen(Color.Green);
> }
>
> private void Button4_Click(object sender, System.EventArgs e)
> {
> APen = new Pen(Color.Black);
> }
>
> private void btnSave_Click(object sender, System.EventArgs e)
> {
> objBitmap.Save(@"c:\Save.bmp", ImageFormat.Bmp);
> objBitmap.Dispose();
> objGraphics.Dispose();
> }
>
> private void Scribbler_Load(object sender, System.EventArgs e)
> {
> objBitmap = new Bitmap(ClientRectangle.Width,
> ClientRectangle.Height);
> } 


Relevant Pages

  • Found the solution
    ... > I am not able to take the screen shot of the windows form based "Smart ... > protected override void Dispose(bool disposing) ... > private void InitializeComponent() ... > private void Connecticon_Click(object sender, ...
    (microsoft.public.dotnet.languages.csharp)
  • Found the solution
    ... > I am not able to take the screen shot of the windows form based "Smart ... > protected override void Dispose(bool disposing) ... > private void InitializeComponent() ... > private void Connecticon_Click(object sender, ...
    (microsoft.public.dotnet.framework.windowsforms.designtime)
  • Found the solution
    ... > I am not able to take the screen shot of the windows form based "Smart ... > protected override void Dispose(bool disposing) ... > private void InitializeComponent() ... > private void Connecticon_Click(object sender, ...
    (microsoft.public.dotnet.framework.windowsforms)
  • Re: Problem displaying a database image on a web form
    ... When the database record is retrieved, ... > the bitmap to a session variable for the rendering aspx to load. ... > private void Page_Load(object sender, ...
    (microsoft.public.dotnet.framework.aspnet)
  • Re: PictureBox ReSize occurs when assigning Image
    ... If I change the size of the bitmap that was previously assigned and do ... private void pictureBox1_Paint(object sender, PaintEventArgs e) ... Graphics g = Graphics.FromImage; ...
    (microsoft.public.dotnet.framework.drawing)