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
InitializeCompo nent();), 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
myBitmapScreenS hot;
//click on this button to capture what's painted on the screen.
private void ScreenCapture_b utton (object sender, EventArgs e)
{
Rectangle screenRect = Screen.PrimaryS creen.WorkingAr ea;
myBitmapScreenS hot = new Bitmap (screenRect.Wid th,
screenRect.Heig ht);
using (Graphics targetGraphics = Graphics.FromIm age
(myBitmapScreen Shot))
{
targetGraphics. CopyFromScreen( 0,0,0,0,new
Size(myBitmapSc reenShot.Width, myBitmapScreenS hot.Height));
}
// now click on this button to save the screenshot to file
private void MySAVEButton_Cl ick(object sender, EventArgs e)
{
String path;
Stream myStream;
saveFileDialog1 .InitialDirecto ry = "C:\
\imageScreenSav e.png";
saveFileDialog1 .Filter = "picture files (*.png)|*.png";
saveFileDialog1 .FilterIndex = 2;
saveFileDialog1 .RestoreDirecto ry = true;
using (Graphics displayGraphics = this.CreateGrap hics())
//create Bitmap to draw into based on existing Graphics
object (p. 222 Sells)
using (Image image = new Bitmap(myBitmap ScreenShot))
//wrap Graphics object around image to draw into
using (Graphics imageGraphics =
Graphics.FromIm age(image))
{
if (saveFileDialog 1.ShowDialog() == DialogResult.OK )
{
if ((myStream = saveFileDialog1 .OpenFile()) !=
null)
{
path = saveFileDialog1 .FileName;
//image.Save(path );//works not at all- why?
Who cares!
image.Save(mySt ream,
System.Drawing. Imaging.ImageFo rmat.Png);
//works fine! (and that's all that matters)
myStream.Close( ); //is this redundant since
wrapped in a 'using'?
}
}
}
}