Получение скриншота экрана

Общие вопросы программирования, алгоритмы и т.п.

Модератор: Модераторы

Получение скриншота экрана

Сообщение mirk » 11.10.2020 22:10:47

Как сделать скриншот экрана в *nix системах (как делает VNC сервер)?
Интересует не только xorg, но и wayland (если есть разница, а она наверное есть).
При этом хотелось бы учесть, что у пользователя может быть запущено видео (плеер или браузер).
mirk
постоялец
 
Сообщения: 316
Зарегистрирован: 24.09.2007 10:03:39

Re: Получение скриншота экрана

Сообщение DYUMON » 13.10.2020 15:30:32

Гугл говорит
Код: Выделить всё
procedure TForm1.Button4Click(Sender: TObject);
var MyBitmap:Graphics.TBitmap;
    ScreenDC:LCLType.HDC;
    WrkJpg:TJpegImage;
begin
  MyBitmap:=Graphics.TBitmap.Create;
  ScreenDC:=LCLIntf.GetDC(0);
  MyBitmap.LoadFromDevice(ScreenDC);


    //Per avere un elenco dei vari formati disponibili (png, bmp, xmp, ecc.):
    //http://wiki.lazarus.freepascal.org/Developing_with_Graphics#Image_formats
    WrkJpg:=TJpegImage.Create;
    try
      WrkJpg.Assign(MyBitmap);
      WrkJpg.SaveToFile(Utf8ToSys(WinTemp + 'Mario.jpg'));
    finally
      FreeAndNil(WrkJpg);
    end;


  LCLIntf.ReleaseDC(0 , ScreenDC);
  FreeAndNil(MyBitmap);
end;
Аватара пользователя
DYUMON
постоялец
 
Сообщения: 214
Зарегистрирован: 11.03.2009 13:32:54

Re: Получение скриншота экрана

Сообщение zoltanleo » 15.10.2020 01:18:40

в дополнение к приведенному коду: у меня даже в демках готовый проект валялся

Изображение
Вложения
project1.zip
(127.39 КБ) Скачиваний: 8
Аватара пользователя
zoltanleo
постоялец
 
Сообщения: 394
Зарегистрирован: 17.10.2013 10:55:01

Re: Получение скриншота экрана

Сообщение Alex2013 » 15.10.2020 01:59:05

В винде работает так :
Код: Выделить всё
function TCaptureForm.CreateSnapshot ( WindowHD : HWND ):TBitmap;
var
    wnd:HWND;
    dc:HDC;
    Bmp:TBitmap;
    r:TRect;

begin
    Bmp:=TMP;
     wnd :=WindowHD;
       if wnd = 0 then
        begin
         dc := GetDC(0);
         Bmp := TBitmap.Create;
         Bmp.SetSize (Screen.Width,Screen.Height);
        end
       else
        begin
        Bmp := TBitmap.Create;
        dc := GetWindowDC(wnd);
         GetWindowRect(wnd,r);
         Bmp.SetSize(r.Right-r.Left,r.Bottom-r.Top);
        end;
       BitBlt(Bmp.Canvas.Handle,0,0,Bmp.Width,Bmp.Height,DC,0,0,SRCCOPY);
       Result:= bmp;
      ReleaseDC(wnd,dc);
end;


Если WindowHD равно нулю захватывает весь экран, а если подставить реальный Handle окна только его (причем неважно перекрыто ли оно другим окнами или нет лишь бы не свернуто )
Alex2013
долгожитель
 
Сообщения: 1856
Зарегистрирован: 03.04.2013 11:59:44

Re: Получение скриншота экрана

Сообщение zoltanleo » 15.10.2020 02:06:59

Alex2013
имхо, лучше пользовать кроссплатформенный способ. Он к тому же и проще.
Аватара пользователя
zoltanleo
постоялец
 
Сообщения: 394
Зарегистрирован: 17.10.2013 10:55:01

Re: Получение скриншота экрана

Сообщение iskander » 15.10.2020 08:30:14

Пользовался вот такой процедурой:
Код: Выделить всё
procedure Screen2File(const aFileName: string);
var
  dc: HDC;
begin
  dc := LclIntf.GetDC(0);
  try
    with TPicture.Create do
      try
        Bitmap.LoadFromDevice(dc);
        SaveToFile(aFileName);
      finally
        Free;
      end;
  finally
    LclIntf.ReleaseDC(0 , dc);
  end;
end;

Формат сохраняемой картинки определяется по расширению файла. Бросит исключение, если формат не поддерживается.
iskander
постоялец
 
Сообщения: 311
Зарегистрирован: 08.01.2012 18:43:34

Re: Получение скриншота экрана

Сообщение Alex2013 » 15.10.2020 10:52:01

zoltanleo писал(а):Alex2013
имхо, лучше пользовать кроссплатформенный способ. Он к тому же и проще.

Так как раз запись скриншота экрана (с нулевым хамбелом ) по моему вполне себе кросс-платформенная....
А вот "выкусывание" конкретного окна кажется нет, но штука реально полезная.
Но да так действительно проще. :idea:
Код: Выделить всё
procedure TForm1.Button1Click(Sender: TObject);
var
  MyBitmap: TBitmap;
  ScreenDC: HDC;
begin
  MyBitmap:= TBitmap.Create;
  try
    ScreenDC:= GetDC(0);
    try
      MyBitmap.LoadFromDevice(ScreenDC);
    finally
      ReleaseDC(0,ScreenDC);
    end;

    Image1.Picture.Assign(MyBitmap);
  finally
    FreeAndNil(MyBitmap);
  end;
end;               

Спасибо, за код попробую !
ЗЫ
Кстати интересно, а для линукса аналог "снятия скринов окон" есть ? Нет понятно, что в GetDC нужно подставить хембел окна, но как его получить (особенно для "чужого" окна )?
Alex2013
долгожитель
 
Сообщения: 1856
Зарегистрирован: 03.04.2013 11:59:44

Re: Получение скриншота экрана

Сообщение iskander » 15.10.2020 12:52:27

Alex2013 писал(а):Нет понятно, что в GetDC нужно подставить хембел окна, но как его получить

А TForm.Handle это по-твоему что?
iskander
постоялец
 
Сообщения: 311
Зарегистрирован: 08.01.2012 18:43:34

Re: Получение скриншота экрана

Сообщение Alex2013 » 15.10.2020 18:46:11

iskander писал(а):
Alex2013 писал(а):Нет понятно, что в GetDC нужно подставить хембел окна, но как его получить

А TForm.Handle это по-твоему что?

TForm.Handl это для "своих" окон, а интересны в первую очередь "чужие" ! :idea:
Есть например такое окно...
Изображение
... и нужно получить что-то вроде этого.
Изображение
Alex2013
долгожитель
 
Сообщения: 1856
Зарегистрирован: 03.04.2013 11:59:44

Re: Получение скриншота экрана

Сообщение Seenkao » 15.10.2020 19:42:37

GetDC(0) - получение хендла основного окна (если память не изменяет, и выше уже скидывали пример)
Насколько я помню, там ещё функции есть, существует окно или нет. Можете методом перебора всё сделать. Но насколько я помню, надо получить хендл основного окна, убрать своё окно, сделать скрин, восстановить своё окно. Ну и сохранить.

Кстати, читайте книжки, Флёнов у себя делал скрины, насколько я помню.
Seenkao
новенький
 
Сообщения: 86
Зарегистрирован: 01.04.2020 03:37:12

Re: Получение скриншота экрана

Сообщение iskander » 18.10.2020 10:48:10

Alex2013 писал(а):а интересны в первую очередь "чужие" !

Для любителей чужих окон в винде есть EnumWindows/EnumChildWindows.
iskander
постоялец
 
Сообщения: 311
Зарегистрирован: 08.01.2012 18:43:34

Re: Получение скриншота экрана

Сообщение Alex2013 » 18.10.2020 21:30:09

iskander писал(а):Для любителей чужих окон в винде есть EnumWindows/EnumChildWindows.

В винде (как видно на скрине ) я более или менее разобрался.
(Правда читал что есть способ через PrintWindows добраться и до свернутых окно - вот это пока "не взлетело" . :roll: )
Alex2013
долгожитель
 
Сообщения: 1856
Зарегистрирован: 03.04.2013 11:59:44


Вернуться в Общее

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4

Рейтинг@Mail.ru