R
raylopez99
Beware newbies: I spent a day before I figured this out: copying a
bitmap (image) file to file is not quite like copying a text file--you
have to do some tricks (see below), like using a "Graphics" object to
wrap around the image (!). It's not so simple as shown in most
examples (where they have a simple image file and hard copy it into a
harddrive along the lines of : image.Save(@"C:\\temp\\myimage.pgn");
That will work, but it's a rare bird that needs this.
The below is adapted from Chris Sells book and from another thread
here. The only thing I have not figured out is whether you need to
use .Close on the stream that the image is stored /backed into--I
think it can be safely deleted, since it's redundant to the using
bracket, but I'll await expert commentary from here.
RL
http://tinyurl.com/5a7p5q (older thread that outlines problem)
I found the solution. It was indeed the pecularities of Image and
Bitmap (which is a subset of Image). It's very bizarre. I assumed
Bitmap and Image are like 'text files' except binary, but in fact you
have to 'wrap them' in a graphics object. See the below complete
code, which works, on a form of screen capture.
Adapted from Chris Sells Chapter 5 "Windows Forms 2.0 Programming"
//declare this member variable before class Form instantiation as a
member variable (that is, outside the class that has
InitializeComponent()
, say just after your second bracket after the
namespace bracket "{" will do, after ' public partial class MyForm:
Form'. Don't initialize, just declare it: Bitmap
myBitmapScreenShot;
//click on this button to capture what's painted on the screen.
private void ScreenCapture_button (object sender, EventArgs e)
{
Rectangle screenRect = Screen.PrimaryScreen.WorkingArea;
myBitmapScreenShot = new Bitmap (screenRect.Width,
screenRect.Height);
using (Graphics targetGraphics = Graphics.FromImage
(myBitmapScreenShot))
{
targetGraphics.CopyFromScreen(0,0,0,0,new
Size(myBitmapScreenShot.Width,myBitmapScreenShot.Height));
}
// now click on this button to save the screenshot to file
private void MySAVEButton_Click(object sender, EventArgs e)
{
String path;
Stream myStream;
saveFileDialog1.InitialDirectory = "C:\
\imageScreenSave.png";
saveFileDialog1.Filter = "picture files (*.png)|*.png";
saveFileDialog1.FilterIndex = 2;
saveFileDialog1.RestoreDirectory = true;
using (Graphics displayGraphics = this.CreateGraphics())
//create Bitmap to draw into based on existing Graphics
object (p. 222 Sells)
using (Image image = new Bitmap(myBitmapScreenShot))
//wrap Graphics object around image to draw into
using (Graphics imageGraphics =
Graphics.FromImage(image))
{
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
if ((myStream = saveFileDialog1.OpenFile()) !=
null)
{
path = saveFileDialog1.FileName;
//image.Save(path);//works not at all- why?
Who cares!
image.Save(myStream,
System.Drawing.Imaging.ImageFormat.Png);
//works fine! (and that's all that matters)
myStream.Close(); //is this redundant since
wrapped in a 'using'?
}
}
}
}
bitmap (image) file to file is not quite like copying a text file--you
have to do some tricks (see below), like using a "Graphics" object to
wrap around the image (!). It's not so simple as shown in most
examples (where they have a simple image file and hard copy it into a
harddrive along the lines of : image.Save(@"C:\\temp\\myimage.pgn");
That will work, but it's a rare bird that needs this.
The below is adapted from Chris Sells book and from another thread
here. The only thing I have not figured out is whether you need to
use .Close on the stream that the image is stored /backed into--I
think it can be safely deleted, since it's redundant to the using
bracket, but I'll await expert commentary from here.
RL
http://tinyurl.com/5a7p5q (older thread that outlines problem)
I found the solution. It was indeed the pecularities of Image and
Bitmap (which is a subset of Image). It's very bizarre. I assumed
Bitmap and Image are like 'text files' except binary, but in fact you
have to 'wrap them' in a graphics object. See the below complete
code, which works, on a form of screen capture.
Adapted from Chris Sells Chapter 5 "Windows Forms 2.0 Programming"
//declare this member variable before class Form instantiation as a
member variable (that is, outside the class that has
InitializeComponent()

namespace bracket "{" will do, after ' public partial class MyForm:
Form'. Don't initialize, just declare it: Bitmap
myBitmapScreenShot;
//click on this button to capture what's painted on the screen.
private void ScreenCapture_button (object sender, EventArgs e)
{
Rectangle screenRect = Screen.PrimaryScreen.WorkingArea;
myBitmapScreenShot = new Bitmap (screenRect.Width,
screenRect.Height);
using (Graphics targetGraphics = Graphics.FromImage
(myBitmapScreenShot))
{
targetGraphics.CopyFromScreen(0,0,0,0,new
Size(myBitmapScreenShot.Width,myBitmapScreenShot.Height));
}
// now click on this button to save the screenshot to file
private void MySAVEButton_Click(object sender, EventArgs e)
{
String path;
Stream myStream;
saveFileDialog1.InitialDirectory = "C:\
\imageScreenSave.png";
saveFileDialog1.Filter = "picture files (*.png)|*.png";
saveFileDialog1.FilterIndex = 2;
saveFileDialog1.RestoreDirectory = true;
using (Graphics displayGraphics = this.CreateGraphics())
//create Bitmap to draw into based on existing Graphics
object (p. 222 Sells)
using (Image image = new Bitmap(myBitmapScreenShot))
//wrap Graphics object around image to draw into
using (Graphics imageGraphics =
Graphics.FromImage(image))
{
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
if ((myStream = saveFileDialog1.OpenFile()) !=
null)
{
path = saveFileDialog1.FileName;
//image.Save(path);//works not at all- why?
Who cares!
image.Save(myStream,
System.Drawing.Imaging.ImageFormat.Png);
//works fine! (and that's all that matters)
myStream.Close(); //is this redundant since
wrapped in a 'using'?
}
}
}
}