Click here to Skip to main content
15,884,099 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
I want to take screenshot using C# for multiple screen games of high definition.It works normally very good but if I am going to take the screenshot of full screen graphics games it shows a black rectangle box.I have googled a lot but did't got any proper solution.So could any one give a solution for that its very urgent for me.More over I have not work with directX .More over my project is in .Net framework 4.5.
Please help me with a proper code example.That is workable regarding this..please guys.

What I have tried:

I have used C# for that.My code is:

 string ScreenPath,directory;
code to initialize:
  string appPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "anticheat");
            try
            {
                if (!Directory.Exists(appPath))
                {
                    Directory.CreateDirectory(appPath);
                }
            }
            catch(Exception)
            {
            }
            directory = appPath;
-------------------------------------------
code to capture image
   public void screenCapture(bool showCursor)
        {
            int noofscreens = 0;         
            Screen[] screens;

            screens = Screen.AllScreens;
            noofscreens = screens.Length;

            Point curPos = new Point(Cursor.Position.X, Cursor.Position.Y);
            Size curSize = new Size();
            curSize.Height = Cursor.Current.Size.Height;
            curSize.Width = Cursor.Current.Size.Width;

            //ScreenPath = "C:\\Users\\user\\Desktop\\sssss.bmp";
            string foldername = LoginFrm.username;
            ScreenPath = directory +"/"+foldername.Replace('@', '_')+"-"+ DateTime.Now.ToString("dd-MMM-yyy hh-mm-ss tt") + ".jpg";
            

            if (!ScreenShot.saveToClipboard)
            {

          
            }

            if (ScreenPath != "" || ScreenShot.saveToClipboard)
            {

                //Conceal this form while the screen capture takes place
                //this.WindowState = System.Windows.Forms.FormWindowState.Minimized;
                //this.TopMost = false;

                //Allow 250 milliseconds for the screen to repaint itself (we don't want to include this form in the capture)
                System.Threading.Thread.Sleep(250);

                Rectangle bounds = Screen.GetBounds(Screen.GetBounds(Point.Empty));
                string fi = "";
                if (ScreenPath != "")
                {
                    fi = new FileInfo(ScreenPath).Extension;
                }

                //===============================================================================
                //this.Visible = false;
                //this.Refresh();
                System.Threading.Thread.Sleep(100);
            
              
             
                int i = 0;

                foreach (var screen in System.Windows.Forms.Screen.AllScreens)
                {
                    ScreenPath = directory + "/" + foldername.Replace('@', '_') + "-" + DateTime.Now.ToString("dd-MMM-yyy hh-mm-ss tt") + "_Sc(" + (i +1)+ ")" + ".jpg";

                    Rectangle bounds1 = screen.Bounds;// screen.GetBounds(Screen.GetBounds(Point.Empty));
                    //Point source = new Point(bounds1.X, bounds1.Y);
                    //Point destination = new Point(bounds1.X + bounds1.Width, bounds1.Y);

                    ScreenShot.CaptureImage(showCursor, curSize, curPos, Point.Empty, Point.Empty, bounds1, ScreenPath, fi);
                    //grabwindow[i] = new Form1(this, "Click to capture screen " + (i + 1).ToString(), screen.Bounds.X, screen.Bounds.Y, screen.Bounds.Width, screen.Bounds.Height, i);
                    //grabwindow[i].Show();
                    i++;
                }
                //===============================================================================








                //ScreenShot.CaptureImage(showCursor, curSize, curPos, Point.Empty, Point.Empty, bounds, ScreenPath, fi);

                //The screen has been captured and saved to a file so bring this form back into the foreground
                //this.WindowState = System.Windows.Forms.FormWindowState.Normal;
                //this.TopMost = true;

                if (ScreenShot.saveToClipboard)
                {
                   
                   // MessageBox.Show("Screen saved to clipboard", "TeboScreen", MessageBoxButtons.OK);

                }
                else
                {

                  //  MessageBox.Show("Screen saved to file", "TeboScreen", MessageBoxButtons.OK);

                }


            }


        }

  
---------------------------------------
class ScreenShot
    {

        public static bool saveToClipboard = false;


        public static void CaptureImage(bool showCursor, Size curSize, Point curPos, Point SourcePoint, Point DestinationPoint, Rectangle SelectionRectangle, string FilePath, string extension)
        {

            DataLayer dl = new DataLayer();
            string ftp = "my Serverpath";

            if(LoginFrm.username!="")
            {
                folder = folder + LoginFrm.username + "/";
            }
            SourcePoint = new Point(SelectionRectangle.X, SelectionRectangle.Y);
            using (Bitmap bitmap = new Bitmap(SelectionRectangle.Width, SelectionRectangle.Height))
            {

                using (Graphics g = Graphics.FromImage(bitmap))
                {
                   
                    g.CopyFromScreen(SourcePoint, DestinationPoint, SelectionRectangle.Size);

                    if (showCursor)
                    {
                        Rectangle cursorBounds = new Rectangle(curPos, curSize);
                        Cursors.Default.Draw(g, cursorBounds);

                    }

                }

                if (saveToClipboard)
                {
                    Image img = (Image)bitmap;
                    Clipboard.SetImage(img);
                }
                else
                {

                    switch (extension)
                    {
                        case ".bmp":
                            bitmap.Save(FilePath, ImageFormat.Bmp);
                            //dl.UploadFile(ftp, folder, username, psw, FilePath);                           
                            break;
                        case ".jpg":
                            bitmap.Save(FilePath, ImageFormat.Jpeg);
                            string fname = Path.GetFileName(FilePath);
                            //dl.UploadFile(ftp, folder, username, psw, FilePath);
                            break;
                        case ".gif":
                            bitmap.Save(FilePath, ImageFormat.Gif);
                            dl.UploadFile(ftp, folder, username, psw, FilePath);
                            break;
                        case ".tiff":
                            bitmap.Save(FilePath, ImageFormat.Tiff);
                            dl.UploadFile(ftp, folder, username, psw, FilePath);
                            break;
                        case ".png":
                            bitmap.Save(FilePath, ImageFormat.Png);
                            dl.UploadFile(ftp, folder, username, psw, FilePath);
                            break;
                        default:
                            bitmap.Save(FilePath, ImageFormat.Jpeg);
                            dl.UploadFile(ftp, folder, username, psw, FilePath);
                            break;
                    }

                }

            }

        }
    }
Posted
Updated 5-May-17 0:01am
v2

You are using the Graphics class which is GDI+ based. But games might use other rendering methods like DirectX or OpenGL.

Especially with DirectX games you have usually no access to the video memory:
When a device is successfully reset (with Device.Reset) or created (with Device.Device) in full-screen operations, the Microsoft Direct3D object that created the device is marked as owning all adapters on that system. This state is known as exclusive mode, and is owned by the Direct3D object. Exclusive mode means that devices created by any other Direct3D object can neither assume full-screen operations nor allocate video memory. In addition, when a Direct3D object assumes exclusive mode, all devices other than the one that went full-screen are placed in lost state.

You might do an extended research to check how screenshots can still be done (e.g. by hooking DirectX):
Take screenshot of DirectX full-screen application - Stack Overflow[^]
C# - Screen capture and Overlays for Direct3D 9, 10 and 11[^]
 
Share this answer
 
Comments
Wessel Beulink 5-May-17 6:15am    
Didn't even know you could use DirectX or OpenGL to capture from the client it self. Very nice to know. Than he should be able to get a 'high definition' capture from there.
Screen capture itself always work or will this be delayed in a game?
Jochen Arndt 5-May-17 6:28am    
You can use them for capturing.

But the problem is that it is usually not possible when not used within the same application because that gets exclusive access.

Therefore, I suggested to do some extended research.
You just use the screenshot function? If you have multiple screen it will collapse to one picture. something like 'high definition' does not exist. It's always screen-bound and will use amount of resolution and pixel rates your computer or gpu is running.
A 1024 * 800 with 2 screens will give you a image of 2048 * 800.

I have 2 capture ways:

ScreenCapture sc = new ScreenCapture();
Image img = sc.CaptureScreen();
this.imageDisplay.Image = img;
sc.CaptureWindowToFile(this.Handle,"C:\\temp2.gif",ImageFormat.Gif);


private static void TakeScreenshotPrivate(string strFilename)
{
	Rectangle objRectangle = Screen.PrimaryScreen.Bounds;
	Bitmap objBitmap = new Bitmap(objRectangle.Right, objRectangle.Bottom);
	Graphics objGraphics = default(Graphics);
	IntPtr hdcDest = default(IntPtr);
	int hdcSrc = 0;
	const int SRCCOPY = 0xcc0020;
	string strFormatExtension = null;

	objGraphics = Graphics.FromImage(objBitmap);

	//-- get a device context to the windows desktop and our destination  bitmaps
	hdcSrc = GetDC(0);
	hdcDest = objGraphics.GetHdc;
	//-- copy what is on the desktop to the bitmap
	BitBlt(hdcDest.ToInt32, 0, 0, objRectangle.Right, objRectangle.Bottom, hdcSrc, 0, 0, SRCCOPY);
	//-- release device contexts
	objGraphics.ReleaseHdc(hdcDest);
	ReleaseDC(0, hdcSrc);

	strFormatExtension = _ScreenshotImageFormat.ToString.ToLower;
	if (System.IO.Path.GetExtension(strFilename) != "." + strFormatExtension) {
		strFilename += "." + strFormatExtension;
	}
	switch (strFormatExtension) {
		case "jpeg":
			BitmapToJPEG(objBitmap, strFilename, 80);
			break;
		default:
			objBitmap.Save(strFilename, _ScreenshotImageFormat);
			break;
	}

	//-- save the complete path/filename of the screenshot for possible later use
	_strScreenshotFullPath = strFilename;
}



Just use screen-bound ranges as shown above in canvas to trim your own single screen if you want single screen images.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900