Skip to content

Commit c37c333

Browse files
committed
WinForms - Add CaptureScreenshotAsync
- Simplification of calling the DevTools method - Moved GetContentSizeAsync from OffScreen into partial class (now accessible from WinForms/WPF/OffScreen). - Added menu option Resolves #4081
1 parent 98cb4cf commit c37c333

File tree

6 files changed

+98
-24
lines changed

6 files changed

+98
-24
lines changed

CefSharp.OffScreen/ChromiumWebBrowser.cs

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -643,24 +643,6 @@ public Task ResizeAsync(int width, int height, float? deviceScaleFactor = null)
643643
return tcs.Task;
644644
}
645645

646-
/// <summary>
647-
/// Size of scrollable area in CSS pixels
648-
/// </summary>
649-
/// <returns>A task that can be awaited to get the size of the scrollable area in CSS pixels.</returns>
650-
public async Task<DevTools.DOM.Rect> GetContentSizeAsync()
651-
{
652-
ThrowExceptionIfDisposed();
653-
ThrowExceptionIfBrowserNotInitialized();
654-
655-
using (var devToolsClient = browser.GetDevToolsClient())
656-
{
657-
//Get the content size
658-
var layoutMetricsResponse = await devToolsClient.Page.GetLayoutMetricsAsync().ConfigureAwait(continueOnCapturedContext:false);
659-
660-
return layoutMetricsResponse.CssContentSize;
661-
}
662-
}
663-
664646
/// <inheritdoc/>
665647
public void Load(string url)
666648
{

CefSharp.WinForms.Example/BrowserForm.Designer.cs

Lines changed: 16 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

CefSharp.WinForms.Example/BrowserForm.cs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System;
66
using System.Collections.Generic;
77
using System.ComponentModel;
8+
using System.Diagnostics;
89
using System.IO;
910
using System.Runtime.InteropServices;
1011
using System.Threading.Tasks;
@@ -649,5 +650,41 @@ private void HideScrollbarsToolStripMenuItemClick(object sender, EventArgs e)
649650

650651
_ = control?.HideScrollbarsAsync();
651652
}
653+
654+
private async void TakeScreenShotMenuItemClick(object sender, EventArgs e)
655+
{
656+
var control = GetCurrentTabControl();
657+
658+
if(control == null)
659+
{
660+
return;
661+
}
662+
663+
var chromiumWebBrowser = (ChromiumWebBrowser)control.Browser;
664+
665+
var contentSize = await chromiumWebBrowser.GetContentSizeAsync();
666+
667+
//Capture current scrollable area
668+
var viewPort = new DevTools.Page.Viewport
669+
{
670+
Width = contentSize.Width,
671+
Height = contentSize.Height,
672+
Scale = 1.0
673+
};
674+
675+
var data = await chromiumWebBrowser.CaptureScreenshotAsync(viewPort: viewPort, captureBeyondViewport: true);
676+
677+
// Make a file to save it to (e.g. C:\Users\[user]\Desktop\CefSharp screenshot.png)
678+
var screenshotPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "CefSharp screenshot" + DateTime.Now.Ticks + ".png");
679+
680+
File.WriteAllBytes(screenshotPath, data);
681+
682+
// Tell Windows to launch the saved image.
683+
Process.Start(new ProcessStartInfo(screenshotPath)
684+
{
685+
// UseShellExecute is false by default on .NET Core.
686+
UseShellExecute = true
687+
});
688+
}
652689
}
653690
}

CefSharp.WinForms/ChromiumWebBrowser.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
using CefSharp.Web;
1313
using CefSharp.WinForms.Internals;
1414
using CefSharp.WinForms.Host;
15+
using CefSharp.DevTools.Page;
16+
using System.Threading.Tasks;
1517

1618
namespace CefSharp.WinForms
1719
{
@@ -477,6 +479,28 @@ public void Load(string url)
477479
}
478480
}
479481

482+
/// <summary>
483+
/// Capture page screenshot.
484+
/// </summary>
485+
/// <param name="format">Image compression format (defaults to png).</param>
486+
/// <param name="quality">Compression quality from range [0..100] (jpeg only).</param>
487+
/// <param name="viewPort">Capture the screenshot of a given region only.</param>
488+
/// <param name="fromSurface">Capture the screenshot from the surface, rather than the view. Defaults to true.</param>
489+
/// <param name="captureBeyondViewport">Capture the screenshot beyond the viewport. Defaults to false.</param>
490+
/// <returns>A task that can be awaited to obtain the screenshot as a byte[].</returns>
491+
public async Task<byte[]> CaptureScreenshotAsync(CaptureScreenshotFormat format = CaptureScreenshotFormat.Png, int? quality = null, Viewport viewPort = null, bool fromSurface = true, bool captureBeyondViewport = false)
492+
{
493+
ThrowExceptionIfDisposed();
494+
ThrowExceptionIfBrowserNotInitialized();
495+
496+
using (var devToolsClient = browser.GetDevToolsClient())
497+
{
498+
var screenShot = await devToolsClient.Page.CaptureScreenshotAsync(format, quality, viewPort, fromSurface, captureBeyondViewport).ConfigureAwait(continueOnCapturedContext: false);
499+
500+
return screenShot.Data;
501+
}
502+
}
503+
480504
/// <summary>
481505
/// The javascript object repository, one repository per ChromiumWebBrowser instance.
482506
/// </summary>

CefSharp/IWebBrowser.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,5 +169,11 @@ public interface IWebBrowser : IChromiumWebBrowserBase
169169
/// <param name="browser">When this method returns, contains the <see cref="IBrowser"/> object reference that matches the specified <paramref name="browserId"/>, or null if no matching instance found.</param>
170170
/// <returns>true if a <see cref="IBrowser"/> instance was found matching <paramref name="browserId"/>; otherwise, false.</returns>
171171
bool TryGetBrowserCoreById(int browserId, out IBrowser browser);
172+
173+
/// <summary>
174+
/// Size of scrollable area in CSS pixels
175+
/// </summary>
176+
/// <returns>A task that can be awaited to get the size of the scrollable area in CSS pixels.</returns>
177+
Task<DevTools.DOM.Rect> GetContentSizeAsync();
172178
}
173179
}

CefSharp/Internals/Partial/ChromiumWebBrowser.Partial.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,21 @@ public bool TryGetBrowserCoreById(int browserId, out IBrowser browser)
399399
return browser != null;
400400
}
401401

402+
/// <inheritdoc/>
403+
public async Task<DevTools.DOM.Rect> GetContentSizeAsync()
404+
{
405+
ThrowExceptionIfDisposed();
406+
ThrowExceptionIfBrowserNotInitialized();
407+
408+
using (var devToolsClient = browser.GetDevToolsClient())
409+
{
410+
//Get the content size
411+
var layoutMetricsResponse = await devToolsClient.Page.GetLayoutMetricsAsync().ConfigureAwait(continueOnCapturedContext: false);
412+
413+
return layoutMetricsResponse.CssContentSize;
414+
}
415+
}
416+
402417
private void InitialLoad(bool? isLoading, CefErrorCode? errorCode)
403418
{
404419
if(IsDisposed)

0 commit comments

Comments
 (0)