使用具有高DPI设置的window.scroll捕获屏幕截图

时间:2017-03-31 20:00:06

标签: javascript c# winforms dpi cefsharp

我正在使用CefSharp 55.0.0 WinForms

为了在CefSharp中截取屏幕截图,我使用JavaScript中的window.scroll滚动网页,并拍摄当前视口的图片。一旦完成,然后再将它缝合在一起。这适用于DPI设置为100%的监视器。但是,如果监视器的DPI大于100%屏幕截图,则无法正常工作并错过内容。

图片1 - 100%

enter image description here

图片2 - 150%

enter image description here

将图像1与图像2进行比较。虽然它们(实际上)具有相同的宽度和高度,但与完美的图像1相比,图像2缺少大部分内容。

DPI设置高于100%时,如何才能正确滚动并捕获屏幕截图,以确保我获得设置为100%时的所有内容?

其他详情

应用程序在app.manifest文件中具有正确的DPI识别设置,Cef.EnableHighDPISupport();方法已在Main内调用Program.cs

截图代码(删节)

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

1 个答案:

答案 0 :(得分:0)

虽然不是一个完美的解决方案,但我找到了一种解决方法,涉及在force-device-scale-factor中将1标记设置为CefSettings。它并不完美,因为浏览器不会在高DPI显示器上缩放,这可能会使用户难以阅读文本。但是,它确实解决了我在屏幕截图中缺少数据的更紧迫问题。

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

这个问题仍有待提出更好的建议,如果有的话。 : - )