2017-03-31 52 views
1

我正在使用CefSharp 55.0.0WinForms使用高DPI設置的window.scroll捕獲屏幕截圖

爲了在CefSharp中拍攝屏幕截圖,我使用JavaScript中的window.scroll滾動網頁並拍攝當前視口的圖像。一旦完成,它就會再次被縫合在一起。這適用於DPI設置爲100%的顯示器。但是,如果顯示器的DPI大於100%屏幕截圖無法按預期工作並錯過內容。

圖像1 - 100%

enter image description here

圖像2 - 150%

enter image description here

比較圖像1到圖像2。雖然它們都(幾乎)具有相同的寬度和高度,圖片2缺少大部分內容,與完美圖片1相比較。

DPI設置高於100%,我該如何正確滾動並截取屏幕截圖,以確保在設置爲100%時獲得所有設置?

其他細節

應用在app.manifest文件具有正確DPI知道設置和Cef.EnableHighDPISupport();已內Program.csMain方法被調用。

截圖代碼(刪節)

int scrollHeight = GetDocHeight(); //some javascript that calcs the height of the document 
int viewportHeight = ClientRectangle.Size.Height; 
int viewportWidth = ClientRectangle.Size.Width; 
int count = 0; 
int pageLeft = scrollHeight; 
bool atBottom = false; 

while (!atBottom) 
{ 
    if (pageLeft > viewportHeight) 
    { 
     await GetBrowser().MainFrame.EvaluateScriptAsync("(function() { window.scroll(0," + (count * viewportHeight) + "); })();"); //I think the issue lies here 
     count++; 
     await PutTaskDelay(); 
     using (Bitmap image = GetCurrentViewScreenshot()) 
     { 
      //just a class that saves the partial images to a disk cache 
      cache.AddImage(count, image); 
     } 
    } 
    else 
    { 

     await GetBrowser().MainFrame.EvaluateScriptAsync("(function() { window.scrollBy(0," + pageLeft + "); })();"); 

     atBottom = true; 
     count++; 

     await PutTaskDelay(); 
     Rectangle cropRect = new Rectangle(new Point(0, viewportHeight - pageLeft), new Size(viewportWidth, pageLeft)); 

     using (Bitmap src = GetCurrentViewScreenshot()) 
     using (Bitmap target = new Bitmap(cropRect.Width, cropRect.Height)) 
     using (Graphics g = Graphics.FromImage(target)) 
     { 
      g.DrawImage(src, new Rectangle(0, 0, target.Width, target.Height), cropRect, GraphicsUnit.Pixel); 
      cache.AddImage(count, target); 
     } 

    } 
    pageLeft = pageLeft - viewportHeight; 
} 

當前視圖截圖方法

private Bitmap GetCurrentViewScreenshot() 
{ 
    int width, height; 
    width = ClientRectangle.Width; 
    height = ClientRectangle.Height; 


    using (Bitmap image = new Bitmap(width, height)) 
    { 
     using (Graphics graphics = Graphics.FromImage(image)) 
     { 
      Point p, upperLeftDestination; 
      Point upperLeftSource = new Point(0, 0); 
      p = new Point(0, 0); 
      upperLeftSource = PointToScreen(p); 
      upperLeftDestination = new Point(0, 0); 
      Size blockRegionSize = ClientRectangle.Size; 
      graphics.CopyFromScreen(upperLeftSource, upperLeftDestination, blockRegionSize); 

     } 
     return new Bitmap(image); 
    } 
} 
+0

使用'viewportHeight'滾動頁面可能會導致您的評論建議的問題。你可能會混淆縮放該值來匹配瀏覽器高度,或者簡單地將瀏覽器的可見寬度/高度作爲瀏覽器。我也在研究重構代碼以減少重複。我也會讓'GetDocHeight'成爲一個適當的異步方法,(避免使用'Wait()')。 – amaitland

+0

謝謝@amaitland。當我回頭看截圖時,我會給它一個大的重構。這個代碼最初是爲'WebBrowser'控件創建的,它爲底層的'Document'提供了整潔的屬性(關於這個糟糕的控件的唯一好處),當我轉換爲'CefSharp'時,有些事情沒有引起注意他們應得的。再次感謝。 – TEK

回答

0

雖然不是一個完美的解決方案,我發現了一個變通方法,包括在force-device-scale-factor標誌設置爲1CefSettings。這並不完美,因爲瀏覽器沒有按高DPI顯示縮放,可能導致用戶難以閱讀文本。但是,它確實解決了我在截圖中丟失數據的更緊迫問題。

CefSettings settings = new CefSettings(); 
settings.CefCommandLineArgs.Add("force-device-scale-factor", "1"); 
Cef.Initialize(settings); 

如果有更好的建議,這個問題仍然存在。 :-)