Javascript 使用window.scroll和高DPI设置捕获屏幕截图
我使用的是Javascript 使用window.scroll和高DPI设置捕获屏幕截图,javascript,c#,winforms,dpi,cefsharp,Javascript,C#,Winforms,Dpi,Cefsharp,我使用的是cefsharp55.0.0WinForms 为了在CefSharp中截图,我使用窗口滚动网页。在JavaScript中滚动,并拍摄当前视口的图像。一旦完成,它将再次缝合在一起。这对于将其DPI设置设置为100%的监视器很好。但是,当显示器的DPI大于100%时,屏幕截图不能按预期工作,并且会丢失内容 图像1-100% 图像2-150% 比较图1和图2。虽然它们(实际上)具有相同的宽度和高度,但与完美的图像1相比,图像2缺少大部分内容 当DPI设置高于100%时,如何正确滚动并捕获
cefsharp55.0.0
WinForms
为了在CefSharp
中截图,我使用窗口滚动网页。在JavaScript中滚动
,并拍摄当前视口的图像。一旦完成,它将再次缝合在一起。这对于将其DPI
设置设置为100%
的监视器很好。但是,当显示器的DPI<代码>大于<代码>100%时,屏幕截图不能按预期工作,并且会丢失内容
图像1-100%
图像2-150%
比较图1和图2。虽然它们(实际上)具有相同的宽度和高度,但与完美的图像1相比,图像2缺少大部分内容
当DPI
设置高于100%
时,如何正确滚动并捕获屏幕截图,以确保获得设置为100%
时所能获得的一切
其他详细信息
应用程序在app.manifest
文件和Cef.EnableHighDPISupport()中具有正确的DPI感知设置在Program.cs
中的Main
方法中调用了code>
屏幕截图代码(节略)
当前视图截图方法
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);
}
}
虽然不是一个完美的解决方案,但我找到了一个解决方案,它涉及在CefSettings
中将force device scale factor
标志设置为1
。它并不完美,因为浏览器没有在高DPI
显示上缩放,这可能会让用户难以阅读文本。然而,它确实解决了我在截图中丢失数据这一更紧迫的问题
CefSettings settings = new CefSettings();
settings.CefCommandLineArgs.Add("force-device-scale-factor", "1");
Cef.Initialize(settings);
如果有更好的建议,这个问题仍然有待解决。:-) 虽然不是一个完美的解决方案,但我找到了一个解决方法,包括在CefSettings
中将强制设备比例因子
标志设置为1
。它并不完美,因为浏览器没有在高DPI
显示上缩放,这可能会让用户难以阅读文本。然而,它确实解决了我在截图中丢失数据这一更紧迫的问题
CefSettings settings = new CefSettings();
settings.CefCommandLineArgs.Add("force-device-scale-factor", "1");
Cef.Initialize(settings);
如果有更好的建议,这个问题仍然有待解决。:-) 如您的评论所示,使用viewportHeight
滚动页面可能会导致问题。您可以随意缩放该值以匹配浏览器的高度,或者简单地将其视为可查看的宽度/高度。我还将考虑重构代码以减少重复。我还想让GetDocHeight
成为一种合适的异步方法(避免使用Wait()
)。谢谢@amaitland。当我回头看屏幕截图时,我会给它一个大的重构。这段代码最初是为WebBrowser
控件创建的,它为底层文档
提供了更整洁的属性(这是该糟糕控件的唯一优点),当我转换为CefSharp
时,有些东西并没有得到应有的关注。再次感谢。如您的评论所示,使用viewportHeight
滚动页面可能会导致问题。您可以随意缩放该值以匹配浏览器的高度,或者简单地将其视为可查看的宽度/高度。我还将考虑重构代码以减少重复。我还想让GetDocHeight
成为一种合适的异步方法(避免使用Wait()
)。谢谢@amaitland。当我回头看屏幕截图时,我会给它一个大的重构。这段代码最初是为WebBrowser
控件创建的,它为底层文档
提供了更整洁的属性(这是该糟糕控件的唯一优点),当我转换为CefSharp
时,有些东西并没有得到应有的关注。再次感谢。