473,287 Members | 2,263 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,287 software developers and data experts.

Saving and loading bmp using graphics object

Vin
Hi,

I am using the following code to draw whatever the user draws using
x,y.

// draws lines directly on a winform.
CreateGraphics().DrawLine(APen, x, y, OldX, OldY);

Now how do I save the drawing on to a bmp file on my harddisk? C# code
in this regard would be very helpful. I tried all forums but invain.

I tried with Graphics object and then

objBitmap=new Bitmap(400, 200, objGraphics);
objBitmap.Save(@"c:\test.bmp", ImageFormat.Bmp);

which didn't work, leaving me with a blank test.bmp.

Also help me load a bmp from hard disk to this form? C# code please.

Anyone out there who could help me?

Cheers
Vin
Nov 16 '05 #1
5 20229
Hi Vin,

The simplest way might be to create a Bitmap the size of your window and
either draw on both Bitmap and graphics or draw on the bitmap and use
DrawImage to draw the bitmap on the graphics.
This way you can also load the bitmap from a file and use DrawImage to
paste it back to the screen

However, this way won't store any undo information. To do this you would
have to store each line drawn in some array or other, possibly a
GraphicsPath.

Your code won't work because simply using DrawLine doesn't retain
information. If something covers your window or you minimize/maximize it
the drawing will be gone. You might want to read Bob Powell's Faq in this
regard.

http://www.bobpowell.net/faqmain.htm

--
Happy Coding!
Morten Wennevik [C# MVP]
Nov 16 '05 #2
Vin
Thanks Morten,

I understand what you want to say.
But in terms of code I have no clue what you are saying.

A c# code snippet would surely do a world of good to me.
GraphicsPath and all, I am still a novice. Even bob powell's FAQ are a
too elaborative and I got lost somewhere.

Help much appreciated

Thanks
Vin

*** Sent via Developersdex http://www.developersdex.com ***
Don't just participate in USENET...get rewarded for it!
Nov 16 '05 #3
First of all, this is not a good way to draw onto the window. You'll find
that if anything causes the window to need repainting (e.g. it is obscured
by some other window, or resized, or minimized, or is moved partially off
the screen and then back on) you'll lose all your drawing.

This is because there is nothing that actually stores what you've drawn onto
the window - you're just drawing onto the screen.

Windows has always relied on the ability of applications to recreate their
appearance on demand. It sends them a message (WM_PAINT) whenever it wants
them to repaint themselves, and in .NET this is manifest through the OnPaint
event in Windows Forms.

So the fact that nothing is actually storing your drawing output should make
it fairly clear that there isn't any method you can call to save the
output...

In fact the output might not even make it onto the screen - if you run the
code below when the window happens to be obscured or minimized, that drawing
won't go anywhere at all, not even onto the screen.

Here's what you should do:

public class MyForm : Form
{
private Bitmap bmp;

... and in whatever function it was that you were going to do your
drawing,
put this code....

bmp = new Bitmap(ClientRectangle.Width, ClientRectangle.Height);
using (Graphics g = Graphics.FromImage(bmp)
{
g.DrawLine(APen, x, y, OldX, OldY);
}

...

protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.DrawImage(bmp, 0, 0);

base.OnPaint(e);
}

}
And now you'll be able to save that image with this code:

bmp.Save("MyBitmap.bmp", ImageFormat.Bmp);
What's been done here is that we've created a Bitmap object to hold the
image. If you want to have the image stored somewhere it's your
responsibility to make that happen, so in this example, that's why we create
the Bitmap.

By overriding OnPaint, we make sure that the contents of the Bitmap get
shown on the screen whenever Windows asks us to refresh our application's
appearance.

And because we've stored the drawing inside a Bitmap, we can now save it out
to disk whenever we like using the code shown above.

To load it back from disk, do this:

bmp = new Bitmap("MyBitmap.bmp");

Hope that helps.
--
Ian Griffiths - http://www.interact-sw.co.uk/iangblog/
DevelopMentor - http://www.develop.com/

"Vin" <kg*******@gmail.com> wrote:> Hi,

I am using the following code to draw whatever the user draws using
x,y.

// draws lines directly on a winform.
CreateGraphics().DrawLine(APen, x, y, OldX, OldY);

Now how do I save the drawing on to a bmp file on my harddisk? C# code
in this regard would be very helpful. I tried all forums but invain.

I tried with Graphics object and then

objBitmap=new Bitmap(400, 200, objGraphics);
objBitmap.Save(@"c:\test.bmp", ImageFormat.Bmp);

which didn't work, leaving me with a blank test.bmp.

Also help me load a bmp from hard disk to this form? C# code please.

Anyone out there who could help me?

Cheers
Vin

Nov 16 '05 #4
Vin
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);
}

Thanks
Vin
Nov 16 '05 #5
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);
}

Nov 16 '05 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Novice | last post by:
I'm afraid I will incur the wraith of Mr. Powell on this one - but I did read his #1 FAQ and some others and I still can't figure this out. I created this little c# app. and I have a PictureBox...
5
by: Steve Marshall | last post by:
Hi all, I am converting an app which used a picturebox to draw graphs etc onto, then saved them to a file. I can certainly draw things onto a picturbox in VB.NET, but how do I save them to a...
5
by: TheGanjaMan | last post by:
Hi everyone, I'm trying to write up a simple image stamper application that stamps the Exif date information from the jpegs that I've taken from my digital camera and saves the new file with the...
4
by: Jake G | last post by:
Hi, I wrote a script to generate links to some pictures that I need to regularly update our site with. Is there a way to write a script that just saves the pics to a directory on my pc so I dont...
6
by: John Kotuby | last post by:
Hi all, I am using a 3rd party program in a VS2005 web project. The tool takes as input a string containing HTML and converts it to RTF. I have been creating a page by dynamically loading...
9
by: she_prog | last post by:
Dear All, I need to save the content of a panel to a bitmap. The panel can have many child controls which also need to be saved. The problem would be solved if I could have the panel saved to a...
2
by: JoeC | last post by:
I have successfully saved and re-loaded binary data but I am having some trouble with some data: I wrote a binary graphics object and it takes data in a BYTE form. Here is the data I have and...
8
by: vicky87.eie | last post by:
I used a picture box to draw lines and rectangle using its graphics object in paint event. Now i need to save those lines i have drawn and print them. I need to know how to save them. I tried...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 7 Feb 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:30 (7.30PM). In this month's session, the creator of the excellent VBE...
0
by: MeoLessi9 | last post by:
I have VirtualBox installed on Windows 11 and now I would like to install Kali on a virtual machine. However, on the official website, I see two options: "Installer images" and "Virtual machines"....
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: Aftab Ahmad | last post by:
So, I have written a code for a cmd called "Send WhatsApp Message" to open and send WhatsApp messaage. The code is given below. Dim IE As Object Set IE =...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: marcoviolo | last post by:
Dear all, I would like to implement on my worksheet an vlookup dynamic , that consider a change of pivot excel via win32com, from an external excel (without open it) and save the new file into a...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.