私はCefSharp 55.0.0
WinForms
を使用しています。高いDPI設定でwindow.scrollを使用してスクリーンショットをキャプチャする
CefSharp
でスクリーンショットを撮るには、JavaScript内でwindow.scroll
を使用してウェブページをスクロールし、現在のビューポートの画像を撮ります。それが完了すると、それは再び一緒に縫い合わせられます。これは、DPI
の設定が100%
に設定されているモニターで問題ありません。ただし、DPI
より大きい100%
のスクリーンショットがある場合、スクリーンショットは期待どおりに機能せず、コンテンツが欠落します。
画像1から100パーセント
画像2 - 彼らは両方(事実上)がありますが150%では
画像2に画像1を比較同一の幅および高さを有し、画像2は、完全な画像1と比較して、コンテンツの大部分を欠いている。
100%
の設定を超えると、設定を100%
に設定した場合のすべての取得を確実にするスクリーンショットを正しくスクロールしてキャプチャするにはどうすればよいですか?
その他の詳細
アプリケーションapp.manifest
ファイルに正しいDPI意識した設定を持っており、Cef.EnableHighDPISupport();
はProgram.cs
内Main
方法で呼び出されました。 (要約)
スクリーンショットコード
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);
}
}
'viewportHeight'を使ってページをスクロールすると、コメントが示唆しているように問題が発生する可能性があります。あなたはブラウザの高さに一致するようにその値をスケーリングするか、単にブラウザとして幅と高さを見ることができます。私は、重複を減らすためにコードをリファクタリングすることも検討しています。私は 'GetDocHeight'を適切な非同期メソッドにします(' Wait() 'の使用を避けてください)。 – amaitland
ありがとうございました。私がスクリーンショットを見ている間、私はそれを大きくリファクタリングします。このコードはもともと 'WebBrowser'コントロールのために作成されたもので、基本的な' Document'にはそれほど優れたものはありませんでしたが、 'CefSharp'に変換したときには注意が払われませんでした彼らは値する。再度、感謝します。 – TEK