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

标签 javascript c# winforms dpi cefsharp

我正在使用 CefSharp 55.0.0 WinForms

为了在 CefSharp 中截取屏幕截图,我在 JavaScript 中使用 window.scroll 滚动网页并拍摄当前视口(viewport)的图像。一旦完成,它就会再次缝合在一起。这对于将 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 感知设置,并且已在 Main 中调用 Cef.EnableHighDPISupport(); > 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;
}

当前 View 截图方法

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

最佳答案

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

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

这个问题仍然开放,需要更好的建议(如果有的话)。 :-)

关于javascript - 使用具有高 DPI 设置的 window.scroll 捕获屏幕截图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43148772/

相关文章:

javascript - jQuery.fadeOut() 函数内部的整数倾斜?

Javascript 函数参数评估

c# - csproj.csdat 文件有什么用

c# - 配置 Enterprise Library 5.0 数据访问应用程序 block

javascript - 使用 jquery 单击后退按钮后,输入字段不会被禁用

javascript - 无法在 Formik onSubmit 中设置错误

c# - EF : Restriction on data types mapping

c# - 将 app.config 中的配置替换为 WCF 服务的代码配置

c# - 在 c# winform 中的所有控件顶部绘制黑色矩形

c++ - 在 Windows 窗体应用程序中隐藏控制台窗口