John_Doe_Was Ответов: 2

Как сделать скриншот с помощью C# для нескольких экранных игр с высоким уровнем дефиниции


Я хочу сделать скриншот с помощью C# для нескольких экранных игр высокой четкости.Обычно он работает очень хорошо, но если я собираюсь сделать снимок экрана полноэкранных графических игр, он показывает черный прямоугольник.Я много гуглил, но так и не нашел подходящего решения.Так что может ли кто-нибудь дать решение для этого очень срочного для меня вопроса?Более того, я не работаю с directX .Более того, мой проект уже готов .Net framework 4.5.
Пожалуйста, помогите мне с правильным примером кода.Это вполне выполнимо в отношении этого...пожалуйста, ребята.

Что я уже пробовал:

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

                }

            }

        }
    }

2 Ответов

Рейтинг:
1

Wessel Beulink

Вы просто используете функцию скриншота? Если у вас есть несколько экранов, он свернется в одну картинку. чего-то вроде "высокой четкости" не существует. Он всегда привязан к экрану и будет использовать количество разрешений и пикселов, на которых работает ваш компьютер или графический процессор.
1024 * 800 с 2 экранами даст вам изображение 2048 * 800.

У меня есть 2 способа захвата:

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



Просто используйте диапазоны с привязкой к экрану, как показано выше в canvas, чтобы обрезать свой собственный один экран, Если вам нужны одноэкранные изображения.


Рейтинг:
0

Jochen Arndt

Вы используете Graphics класс, основанный на GDI+. Но игры могут использовать и другие методы рендеринга, такие как DirectX или OpenGL.

Особенно с играми DirectX у вас обычно нет доступа к видеопамяти:

Когда устройство успешно сброшено (с помощью Device.Сброс) или созданный (с устройством.Устройство) в полноэкранных операциях объект Microsoft Direct3D, создавший устройство, помечается как владелец всех адаптеров в этой системе. Это состояние называется эксклюзивным режимом и принадлежит объекту Direct3D. Эксклюзивный режим означает, что устройства, созданные любым другим объектом Direct3D, не могут ни выполнять полноэкранные операции, ни выделять видеопамять. Кроме того, когда объект Direct3D переходит в эксклюзивный режим, все устройства, кроме того, которое перешло в полноэкранный режим, помещаются в потерянное состояние.

Вы можете провести расширенное исследование, чтобы проверить, как все еще можно делать скриншоты (например, подключив DirectX):
Сделайте снимок экрана полноэкранного приложения DirectX - Stack Overflow[^]
C# - захват экрана и наложение для Direct3D 9, 10 и 11[^]


Wessel Beulink

Даже не знал,что вы можете использовать DirectX или OpenGL для захвата с самого клиента. Очень приятно это знать. Чем он должен быть в состоянии получить захват "высокой четкости" оттуда.
Сам захват экрана всегда работает или это будет отложено в игре?

Jochen Arndt

Вы можете использовать их для захвата.

Но проблема в том, что это обычно невозможно, когда оно не используется в одном приложении, потому что оно получает эксклюзивный доступ.

Поэтому я предложил провести некоторые расширенные исследования.