DCEF3: как сделать скриншот

Как получить скриншот браузера в DCEF3?

Я создаю такой браузер без VCL. TakePicture метод будет работать только если

  • Отладчик не используется
  • Если используется ShowWindow

    var
      info: TCefWindowInfo;
      Settings: TCefBrowserSettings;
    begin
      FillChar(info, SizeOf(info), 0);
      info.width := width;
      info.height := height;
      FillChar(Settings, SizeOf(TCefBrowserSettings), 0);
      Settings.Size := SizeOf(TCefBrowserSettings);
      GetSettings(Settings);
      CefBrowserHostCreateBrowser(@info, FHandler, FDefaultUrl, @settings, nil);
    end;
    
    procedure TakePicture(const Browser: ICefBrowser; Height, Width: Integer);
    var
      DC: HDC;
      Bmp : TBitmap;
      Handle : HWND;
      Rect : trect;
      BarHeight : integer;
      BarLeft : integer;
    begin
      Bmp := TBitmap.Create;
      Bmp.PixelFormat := pf32bit;
      Handle := Browser.Host.WindowHandle;
      ShowWindow(handle, SW_RESTORE); // will work only if this is used otherwise black image!
      BarLeft := GetSystemMetrics(SM_CXFRAME);
      BarHeight := GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYFRAME);
      GetWindowRect(Handle, Rect);
      DC := GetDC(Handle);
      Bmp.Width := Rect.Right - Rect.Left;
      Bmp.Height := (Rect.Bottom - Rect.Top);
      BitBlt(Bmp.Canvas.Handle, 0, 0, Bmp.Width, Bmp.Height, DC, -BarLeft, -BarHeight, SRCCOPY);
      ReleaseDC(Handle, DC);
      Bmp.SaveToFile('c:\test.bmp');
      Bmp.Free;
    end;
    

1 ответ

Это в основном закадровый рендеринг. В папке demos DCEF3 вы найдете проект "вне экрана". Код, который вы ищете, находится в OnPaint событие TChromiumOSR, Он рендерится в TBitmap32, но любой битовый массив может работать. Обратите внимание, что он был оптимизирован для рисования только так называемых "грязных" областей (тех, которые изменились со времени последней рисования), но если вы делаете скриншот, это не то, что вам нужно. В моем извлечении из репозитория есть закомментированная строка, показывающая наивный случай просто нарисовать все:

SomeBitmap.SetSize(width, height);
Move(buffer^, SomeBitmap32.Bits^, width * height * 4);

Это мое лучшее предположение, что магическое число 4 представляет 4 байта (32 бита).

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

Другие вопросы по тегам