CSharp/C# >> Screen Capture (Screen Copying) example / the perils of Image/ Bitmap copying to file

by raylopez99 » Sat, 30 Aug 2008 05:59:55 GMT

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'?
}
}
}

}

CSharp/C# >> Screen Capture (Screen Copying) example / the perils of Image/ Bitmap copying to file

by Mark Salsbery [MVP] » Sat, 30 Aug 2008 08:19:38 GMT



I'm not sure what you're trying to say.

Saving Bitmaps has nothing to do with the Graphics class.

Bitmap bits are often written to directly, which doesn't involve a Graphics.

Creating a Graphics from a Bitmap lets you use the Graphics methods to draw
on the Bitmap.

Cheers,
Mark

--
Mark Salsbery
Microsoft MVP - Visual C++

CSharp/C# >> Screen Capture (Screen Copying) example / the perils of Image/ Bitmap copying to file

by raylopez99 » Sat, 30 Aug 2008 19:10:08 GMT

On Aug 29, 5:19爌m, "Mark Salsbery [MVP]"




I'm sure you're right, but, since this particular application was for
a screenshot (which uses the Graphics class), I could not get it to
work until I wrapped the Bitmap in the graphics class as shown. The
bitmap was stored in a picturebox, which I thought was
'static' (doesn't change on Paint) but I could not store it. Perhaps
the problem was I was downcasting from Image to Bitmap (not clear if I
was, but see the link in the original thread), which apparently is not
good. In any event, following the template I posted, and upcasting
from Bitmap to Image, it worked and the screenshot is fine, and saves
properly.

All's well that ends well, which is all you can ever hope for in these
complex managed languages (unless you want to dive under the hood and
get into assembly-like language and decorator classes, vtables and
what not to see what went wrong).

RL

Similar Threads

1. Very Simple Screen Capture Example?

2. capture the screen bitmap

I want capture the screen bitmap.use the code below,it is 
slow,use the 0.6 second.How can i get good idea to do this?

        CRect rc;
	HWND hDesktopWnd= ::GetDesktopWindow();
	::GetWindowRect(hDesktopWnd, &rc);
	int width=rc.Width();
	int height=rc.Height();
	HDC hdc = ::GetDC(hDesktopWnd);
	HBITMAP hBmp = CreateCompatibleBitmap(hdc, 
width,height);
	HBITMAP holdBmp=(HBITMAP)::SelectObject
(MemoDC,hBmp);
	BitBlt(MemoDC, 0 , 0,width, height, hdc, 0, 0, 
SRCCOPY);

         LPBITMAPINFO    pbmi;
	pbmi->bmiHeader.biWidth =width;
	pbmi->bmiHeader.biHeight =height;
         //
	GetDIBits
(MemoDC,hBmp,0,height,m_plbits,pbmi,DIB_RGB_COLORS);

3. screen capture bitmap

4. Capture DirectShow Screen to a bitmap using BCB 5.0

Hi, I want to capture the windows media video to a bitmap handle, I hope 
someone can help me. By using the Bitblt API function, a black screen was 
copied. The result is same as pressing "Print Screen" button to save a 
picture to clipboard. I know there is a method to do it by using Visual C++ 
but there is very few documentation on BCB. Also, there is a VCL component 
call "DSPACK" which can be used under BCB 6 or Dephi. The package provided 
can't compile successfully under BCB 5.  Many examples from the web are not 
designed for BCB, these examples can't link successfully even if it was 
converted to a BCB project.
I have Direct X 9.0 and Windows Media Player 9 installed on my system. Also, 
I download the Direct X 9 library and dlls and headers for BCB 5, can anyone 
give me some code which can work properly under BCB 5? 


5. Split Screen Copy Problems - CSharp/C#

6. Copy a screen area

How I can copy an screen area (in C# Pocket PC) in order to modify and then 
to restore de original content ?

Thanks in advance.

7. copy text on the screen as text? - CSharp/C#

8. Split Screen Copy Problems

This is a cross post....

My problem is when I am using the split screen editor and I copy and paste
from the bottom pane to the top pane, the top pane will reposition itself to
where the bottom pane is pointed to and I loose my place in the upper pane.

Has anyone experiences this, and is there a setting somewhere to change this
behavior?

Thanks.

Mike

 XXXX@XXXXX.COM