olejkaok
@olejkaok

Как правильно создать скриншот неактивного окна?

Здравствуйте.
Мне необходимо сделать скриншот в хендле окна по указанным координатам(само окно может быть свернуто)
У меня есть более менее рабочий пример, но в нужной для меня игре(GTA 5) он делает скриншот просто черного квадрата.
Вот мой нынешний код:
public static void CaptureWindow(int posX, int posY, int wWidth, int wHeight)
        {
            RECT rect;
            GetWindowRect(hWnd, out rect);
            using (var image = new Bitmap(rect.Right - rect.Left, rect.Bottom - rect.Top))
            {
                using (var graphics = Graphics.FromImage(image))
                {
                    var hdcBitmap = graphics.GetHdc();
                    PrintWindow(hWnd, hdcBitmap, 0);
                    graphics.ReleaseHdc(hdcBitmap);
                }
                var newImage = new Bitmap(wWidth, wHeight);

                int newY = -1;
                int newX = -1;

                for (int y = posY; y < posY + wHeight; y++)
                {
                    newY++;
                    for (int x = posX; x < posX + wWidth; x++)
                    {
                        newX++;
                        newImage.SetPixel(newX, newY, image.GetPixel(x, y));
                        if (newX == wWidth - 1)
                        {
                            newX = -1;
                        }
                    }
                }
                image.Save("Example1.jpg");
                newImage.Save("Example.jpg");

            }
        }


А вот такой скриншот сохраняет из GTA 5(
608b351868c6b798135918.jpeg
  • Вопрос задан
  • 203 просмотра
Пригласить эксперта
Ответы на вопрос 3
@antonwx
Переключите игру в режим borderless window или window для начала.
В полноценном фулскрине можно сделать скриншот ТОЛЬКО когда окно активно. И для этого придётся хукать directx, ваш код не пойдёт.
Многие игры, поддерживающие сворачивание, останавливают отрисовку в этот момент. Даже в оконном режиме. Это тоже надо учитывать, и способов обхода в данном случае нет.
Ответ написан
@cicatrix
было бы большой ошибкой думать
Когда Direct3d переходит в полноэкранный режим, оно получает эксклюзивный прямой доступ к видеокарте (то есть, минуя ОС), поэтому стандартные средства операционной системы для получения скриншотов не подойдут. ОС понятия не имеет, что там внутри окна нарисовано. Для получения скриншота необходимо зацепляться за рендерер.

Taking the screenshot itself is relatively straightforward. Once the scene has been rendered, the Direct3D device offers a GetRenderTarget function that returns a pointer to a Direct3D surface with the current scene. Using a SurfaceToBitmap function, the RenderTarget can be converted to a Bitmap object, which can then be saved as either a JPEG or PNG to disk. Below is an example of the code involved:

Bitmap screenshot = Funcs.SurfaceToBitmap(device.GetRenderTarget(0));
screenshot.Save(Frame.ToString() + ".jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
screenshot.Dispose();


https://www.apharmony.com/software-sagacity/2014/0...
Ответ написан
@user6669991
Эх, ребятки! Я то думал сейчас что интересненькое прочту! Автор вопроса имел в виду может быть не свернутое в трей окно ( в этом случае - да, всякие отрисовки прекращаются и игра замирает), а просто неактивное окно на заднем плане экрана (игра не в full screen, а в window screen). В этом случае многие игры продолжают рендеринг в своем окне, хоть юзер этого и не видит. Думаю - там все дело в каком нибудь флажке-переключателе окна (активное-неактивное). Для Оси все эти окна активные, процессы идут в каждом, просто юзеру подсовывается то или другое окно на первый план
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы