/// <summary> /// This method scrolls element into view if needed, and then uses <seealso cref="Page.ScreenshotBase64Async(ScreenshotOptions)"/> to take a screenshot of the element. /// If the element is detached from DOM, the method throws an error. /// </summary> /// <returns>Task which resolves to a <see cref="string"/> containing the image data as base64.</returns> /// <param name="options">Screenshot options.</param> public async Task <string> ScreenshotBase64Async(ScreenshotOptions options) { var needsViewportReset = false; var boundingBox = await BoundingBoxAsync().ConfigureAwait(false); if (boundingBox == null) { throw new PuppeteerException("Node is either not visible or not an HTMLElement"); } var viewport = Page.Viewport; if (viewport != null && (boundingBox.Width > viewport.Width || boundingBox.Height > viewport.Height)) { var newRawViewport = JObject.FromObject(viewport); newRawViewport.Merge(new ViewPortOptions { Width = (int)Math.Max(viewport.Width, Math.Ceiling(boundingBox.Width)), Height = (int)Math.Max(viewport.Height, Math.Ceiling(boundingBox.Height)) }); await Page.SetViewportAsync(newRawViewport.ToObject <ViewPortOptions>()).ConfigureAwait(false); needsViewportReset = true; } await ExecutionContext.EvaluateFunctionAsync(@"function(element) { element.scrollIntoView({ block: 'center', inline: 'center', behavior: 'instant'}); }", this).ConfigureAwait(false); await ScrollIntoViewIfNeededAsync().ConfigureAwait(false); boundingBox = await BoundingBoxAsync().ConfigureAwait(false); if (boundingBox == null) { throw new PuppeteerException("Node is either not visible or not an HTMLElement"); } var getLayoutMetricsResponse = await Client.SendAsync <GetLayoutMetricsResponse>("Page.getLayoutMetrics").ConfigureAwait(false); var clip = boundingBox; clip.X += getLayoutMetricsResponse.LayoutViewport.PageX; clip.Y += getLayoutMetricsResponse.LayoutViewport.PageY; options.Clip = boundingBox.ToClip(); var imageData = await Page.ScreenshotBase64Async(options).ConfigureAwait(false); if (needsViewportReset) { await Page.SetViewportAsync(viewport).ConfigureAwait(false); } return(imageData); }
/// <summary> /// This method scrolls element into view if needed, and then uses <seealso cref="Page.ScreenshotDataAsync(ScreenshotOptions)"/> to take a screenshot of the element. /// If the element is detached from DOM, the method throws an error. /// </summary> /// <returns>The task</returns> /// <param name="file">The file path to save the image to. The screenshot type will be inferred from file extension. /// If path is a relative path, then it is resolved relative to current working directory. If no path is provided, /// the image won't be saved to the disk.</param> /// <param name="options">Screenshot options.</param> public async Task ScreenshotAsync(string file, ScreenshotOptions options) { var fileInfo = new FileInfo(file); options.Type = fileInfo.Extension.Replace(".", string.Empty); var data = await ScreenshotDataAsync(options); using (var fs = new FileStream(file, FileMode.Create, FileAccess.Write)) { await fs.WriteAsync(data, 0, data.Length); } }
/// <summary> /// This method scrolls element into view if needed, and then uses <seealso cref="Page.ScreenshotDataAsync(ScreenshotOptions)"/> to take a screenshot of the element. /// If the element is detached from DOM, the method throws an error. /// </summary> /// <returns>The task</returns> /// <param name="file">The file path to save the image to. The screenshot type will be inferred from file extension. /// If path is a relative path, then it is resolved relative to current working directory. If no path is provided, /// the image won't be saved to the disk.</param> /// <param name="options">Screenshot options.</param> public async Task ScreenshotAsync(string file, ScreenshotOptions options) { if (!options.Type.HasValue) { options.Type = ScreenshotOptions.GetScreenshotTypeFromFile(file); } var data = await ScreenshotDataAsync(options).ConfigureAwait(false); using (var fs = AsyncFileHelper.CreateStream(file, FileMode.Create)) { await fs.WriteAsync(data, 0, data.Length).ConfigureAwait(false); } }
/// <summary> /// This method scrolls element into view if needed, and then uses <seealso cref="Page.ScreenshotDataAsync(ScreenshotOptions)"/> to take a screenshot of the element. /// If the element is detached from DOM, the method throws an error. /// </summary> /// <returns>The task</returns> /// <param name="file">The file path to save the image to. The screenshot type will be inferred from file extension. /// If path is a relative path, then it is resolved relative to current working directory. If no path is provided, /// the image won't be saved to the disk.</param> /// <param name="options">Screenshot options.</param> public async Task ScreenshotAsync(string file, ScreenshotOptions options) { if (!options.Type.HasValue) { options.Type = ScreenshotOptions.GetScreenshotTypeFromFile(file); } var data = await ScreenshotDataAsync(options); using (var fs = new FileStream(file, FileMode.Create, FileAccess.Write)) { await fs.WriteAsync(data, 0, data.Length); } }
public async Task ScreenshotAsync(string file, ScreenshotOptions options) { var fileInfo = new FileInfo(file); options.Type = fileInfo.Extension.Replace(".", string.Empty); var stream = await ScreenshotStreamAsync(options); using (var fs = new FileStream(file, FileMode.Create, FileAccess.Write)) { byte[] bytesInStream = new byte[stream.Length]; stream.Read(bytesInStream, 0, bytesInStream.Length); fs.Write(bytesInStream, 0, bytesInStream.Length); } }
/// <summary> /// This method scrolls element into view if needed, and then uses <seealso cref="Page.ScreenshotStreamAsync(ScreenshotOptions)"/> to take a screenshot of the element. /// If the element is detached from DOM, the method throws an error. /// </summary> /// <returns>The tas with the image streamk</returns> /// <param name="options">Screenshot options.</param> public async Task <Stream> ScreenshotStreamAsync(ScreenshotOptions options) { await ScrollIntoViewIfNeededAsync(); dynamic metrics = await _client.SendAsync("Page.getLayoutMetrics") as JObject; var boundingBox = await BoundingBoxAsync(); if (boundingBox == null) { throw new PuppeteerException("Node is not visible"); } boundingBox.X += metrics.layoutViewport.pageX.ToObject <decimal>(); boundingBox.Y += metrics.layoutViewport.pageY.ToObject <decimal>(); options.Clip = boundingBox.ToClip(); return(await Page.ScreenshotStreamAsync(options)); }
/// <summary> /// This method scrolls element into view if needed, and then uses <seealso cref="Page.ScreenshotDataAsync(ScreenshotOptions)"/> to take a screenshot of the element. /// If the element is detached from DOM, the method throws an error. /// </summary> /// <returns>Task which resolves to a <see cref="byte"/>[] containing the image data.</returns> /// <param name="options">Screenshot options.</param> public async Task <byte[]> ScreenshotDataAsync(ScreenshotOptions options) { var needsViewportReset = false; var boundingBox = await AssertBoundingBoxAsync(); var viewport = Page.Viewport; if (boundingBox.Width > viewport.Width || boundingBox.Height > viewport.Height) { var newRawViewport = JObject.FromObject(viewport); newRawViewport.Merge(new ViewPortOptions { Width = (int)Math.Max(viewport.Width, Math.Ceiling(boundingBox.Width)), Height = (int)Math.Max(viewport.Height, Math.Ceiling(boundingBox.Height)) }); await Page.SetViewportAsync(newRawViewport.ToObject <ViewPortOptions>()); needsViewportReset = true; } await ExecutionContext.EvaluateFunctionAsync(@"function(element) { element.scrollIntoView({ block: 'center', inline: 'center', behavior: 'instant'}); }", this); boundingBox = await AssertBoundingBoxAsync(); var getLayoutMetricsResponse = await Client.SendAsync <GetLayoutMetricsResponse>("Page.getLayoutMetrics"); var clip = boundingBox; clip.X += getLayoutMetricsResponse.LayoutViewport.PageX; clip.Y += getLayoutMetricsResponse.LayoutViewport.PageY; options.Clip = boundingBox.ToClip(); var imageData = await Page.ScreenshotDataAsync(options); if (needsViewportReset) { await Page.SetViewportAsync(viewport); } return(imageData); }
public async Task <Stream> ScreenshotStreamAsync(ScreenshotOptions options) { string screenshotType = null; if (!string.IsNullOrEmpty(options.Type)) { if (options.Type != "png" && options.Type != "jpeg") { throw new ArgumentException($"Unknown options.type {options.Type}"); } screenshotType = options.Type; } if (string.IsNullOrEmpty(screenshotType)) { screenshotType = "png"; } if (options.Quality.HasValue) { if (screenshotType == "jpeg") { throw new ArgumentException($"options.Quality is unsupported for the {screenshotType} screenshots"); } if (options.Quality < 0 || options.Quality > 100) { throw new ArgumentException($"Expected options.quality to be between 0 and 100 (inclusive), got {options.Quality}"); } } if (options.Clip != null && options.FullPage) { throw new ArgumentException("options.clip and options.fullPage are exclusive"); } return(await _screenshotTaskQueue.Enqueue(() => PerformScreenshot(screenshotType, options))); }
/// <summary> /// This method scrolls element into view if needed, and then uses <seealso cref="Page.ScreenshotDataAsync(ScreenshotOptions)"/> to take a screenshot of the element. /// If the element is detached from DOM, the method throws an error. /// </summary> /// <returns>Task which resolves to a <see cref="Stream"/> containing the image data.</returns> /// <param name="options">Screenshot options.</param> public async Task <Stream> ScreenshotStreamAsync(ScreenshotOptions options) => new MemoryStream(await ScreenshotDataAsync(options).ConfigureAwait(false));
/// <summary> /// This method scrolls element into view if needed, and then uses <seealso cref="Page.ScreenshotDataAsync(ScreenshotOptions)"/> to take a screenshot of the element. /// If the element is detached from DOM, the method throws an error. /// </summary> /// <returns>Task which resolves to a <see cref="byte"/>[] containing the image data.</returns> /// <param name="options">Screenshot options.</param> public async Task <byte[]> ScreenshotDataAsync(ScreenshotOptions options) => Convert.FromBase64String(await ScreenshotBase64Async(options).ConfigureAwait(false));
/// <summary> /// This method scrolls element into view if needed, and then uses <seealso cref="Page.ScreenshotDataAsync(ScreenshotOptions)"/> to take a screenshot of the element. /// If the element is detached from DOM, the method throws an error. /// </summary> /// <returns>Task which resolves to a <see cref="Stream"/> containing the image data.</returns> /// <param name="options">Screenshot options.</param> public async Task <Stream> ScreenshotStreamAsync(ScreenshotOptions options) => new MemoryStream(await ScreenshotDataAsync(options));
public static async Task Main(string[] args) { var currentDirectory = Directory.GetCurrentDirectory(); var downloadPath = Path.Combine(currentDirectory, "CustomChromium"); Console.WriteLine($"Attemping to set up puppeteer to use Chromium found under directory {downloadPath} "); if (!Directory.Exists(downloadPath)) { Console.WriteLine("Custom directory not found. Creating directory"); Directory.CreateDirectory(downloadPath); } Console.WriteLine("Downloading Chromium..."); var browserFetcherOptions = new BrowserFetcherOptions { Path = downloadPath }; var browserFetcher = new BrowserFetcher(browserFetcherOptions); await browserFetcher.DownloadAsync(BrowserFetcher.DefaultRevision); var executablePath = browserFetcher.GetExecutablePath(BrowserFetcher.DefaultRevision); if (string.IsNullOrEmpty(executablePath)) { Console.WriteLine("Custom Chromium location is empty. Unable to start Chromium. Exiting.\n Press any key to continue"); Console.ReadLine(); return; } Console.WriteLine($"Attemping to start Chromium using executable path: {executablePath}"); var options = new LaunchOptions { Headless = true, ExecutablePath = executablePath }; using (var browser = await Puppeteer.LaunchAsync(options)) using (var page = await browser.NewPageAsync()) { await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision); await page.SetViewportAsync(new ViewPortOptions { Width = 1920, Height = 1080 }); var waitUntil = new NavigationOptions { Timeout = 0, WaitUntil = new[] { WaitUntilNavigation.Networkidle0 } }; string url = "https://github.com/puppeteer/puppeteer/issues/1345"; await page.GoToAsync(url, waitUntil); #region Screenshot Dashboard: var optionsScreenShot = new ScreenshotOptions { FullPage = true }; //Đường dẫn lưu file var savePath = Path.Combine(currentDirectory, "Capture"); if (!Directory.Exists(savePath)) { Console.WriteLine("SavePath directory not found. Creating directory"); Directory.CreateDirectory(savePath); } string date = DateTime.Now.ToString("yyyyMMddHHmmss"); var outputfile = savePath + "/capture_" + date + ".png"; await page.ScreenshotAsync(outputfile, optionsScreenShot); Console.WriteLine("Capture completed! Path: " + outputfile, ConsoleColor.Green); #endregion await page.CloseAsync(); } return; }
private async Task <Stream> PerformScreenshot(string format, ScreenshotOptions options) { await _client.SendAsync("Target.activateTarget", new { targetId = _target.TargetId }); var clip = options.Clip != null?options.Clip.Clone() : null; if (clip != null) { clip.Scale = 1; } if (options != null && options.FullPage) { dynamic metrics = await _client.SendAsync("Page.getLayoutMetrics"); var width = Convert.ToInt32(Math.Ceiling(Convert.ToDecimal(metrics.contentSize.width.Value))); var height = Convert.ToInt32(Math.Ceiling(Convert.ToDecimal(metrics.contentSize.height.Value))); // Overwrite clip for full page at all times. clip = new Clip { X = 0, Y = 0, Width = width, Height = height, Scale = 1 }; var mobile = _viewport.IsMobile; var deviceScaleFactor = _viewport.DeviceScaleFactor; var landscape = _viewport.IsLandscape; var screenOrientation = landscape ? new ScreenOrientation { Angle = 90, Type = ScreenOrientationType.LandscapePrimary } : new ScreenOrientation { Angle = 0, Type = ScreenOrientationType.PortraitPrimary }; await _client.SendAsync("Emulation.setDeviceMetricsOverride", new { mobile, width, height, deviceScaleFactor, screenOrientation }); } if (options != null && options.OmitBackground) { await _client.SendAsync("Emulation.setDefaultBackgroundColorOverride", new { color = new { r = 0, g = 0, b = 0, a = 0 } }); } dynamic screenMessage = new ExpandoObject(); screenMessage.format = format; if (options.Quality.HasValue) { screenMessage.quality = options.Quality.Value; } if (clip != null) { screenMessage.clip = clip; } JObject result = await _client.SendAsync("Page.captureScreenshot", screenMessage); if (options != null && options.OmitBackground) { await _client.SendAsync("Emulation.setDefaultBackgroundColorOverride"); } if (options != null && options.FullPage) { await SetViewport(_viewport); } var buffer = Convert.FromBase64String(result.GetValue("data").Value <string>()); return(new MemoryStream(buffer)); }