如何使用C#截取高定义的多屏幕游戏截图 [英] How to take screenshot using C# for multiple screen games of high defination

查看:151
本文介绍了如何使用C#截取高定义的多屏幕游戏截图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用C#截取高清晰度的多屏幕游戏截图。它通常非常好但是如果我要拍全屏图形游戏的屏幕截图,它会显示一个黑色的矩形框。我已经google了很多但是没有任何合适的解决方案。任何人都可以为我提供解决方案对我来说非常迫切。更多的是我没有使用directX。更多我的项目是在.Net framework 4.5。

请帮我一个正确的代码示例。这对于这个人来说是可行的。请大家支持。



我尝试了什么:



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;
                    }

                }

            }

        }
    }

推荐答案

您正在使用基于GDI +的 Graphics 类。但游戏可能会使用其他渲染方法,如DirectX或OpenGL。



特别是对于DirectX游戏,您通常无法访问视频内存:

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:

当设备成功重置(使用Device.Reset)或在全屏操作中创建(使用Device.Device)时,Microsoft Direct3D创建设备的对象标记为拥有该系统上的所有适配器。此状态称为独占模式,由Direct3D对象拥有。独占模式意味着由任何其他Direct3D对象创建的设备既不能采用全屏操作也不能分配视频内存。此外,当Direct3D对象采用独占模式时,除全屏之外的所有设备都将处于丢失状态。

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.



您可能会进行扩展研究以检查屏幕截图仍然可以完成(例如通过挂钩DirectX):

截取DirectX全屏应用程序的截图 - Stack Overflow [ ^ ]

C# - Direct3D 9,10和11的屏幕截图和叠加层 [ ^ ]


您只需使用屏幕截图功能?如果您有多个屏幕,它将折叠为一张图片。像'高清'这样的东西不存在。它总是受屏幕限制,会使用计算机或gpu运行的分辨率和像素速率。

1024 * 800的2个屏幕将为您提供2048 * 800的图像。



我有2种捕获方式:



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.


这篇关于如何使用C#截取高定义的多屏幕游戏截图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆