Take screenshots of webpages or HTML files in .Net (C#)
Capturing screenshots of webpages programmatically is a valuable capability for automated testing, documentation, and monitoring. In this guide, we will explore how to capture screenshots of webpages and HTML files using .NET (C#).
Prerequisites
To follow along with this tutorial, you will need:
- .NET 6.0 or later
- Visual Studio 2022 or Visual Studio Code
- NuGet Package Manager
Using selenium webdriver
Selenium WebDriver is a powerful tool for browser automation that includes screenshot capabilities. First, install the required NuGet packages by adding them to your project file or using the Package Manager Console:
Using Package Manager Console:
Install-Package Selenium.WebDriver -Version 4.16.2
Install-Package Selenium.WebDriver.ChromeDriver -Version 120.0.6099.7100
Alternatively, include the following in your project file:
<PackageReference Include="Selenium.WebDriver" Version="4.16.2" />
<PackageReference Include="Selenium.WebDriver.ChromeDriver" Version="120.0.6099.7100" />
Here's a basic example of capturing a webpage screenshot:
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;
public class ScreenshotCapture
{
public static void CaptureWebpage(string url, string outputPath)
{
var options = new ChromeOptions();
options.AddArgument("--headless"); // Run in headless mode
using (var driver = new ChromeDriver(options))
{
driver.Navigate().GoToUrl(url);
// Wait for the page to load completely
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until(d => ((IJavaScriptExecutor)d).ExecuteScript("return document.readyState").Equals("complete"));
// Capture the screenshot
var screenshot = ((ITakesScreenshot)driver).GetScreenshot();
screenshot.SaveAsFile(outputPath, ScreenshotImageFormat.Png);
}
}
}
Capturing local HTML files
To capture screenshots of local HTML files, use the file://
protocol:
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;
public static void CaptureLocalHtml(string htmlFilePath, string outputPath)
{
var absolutePath = Path.GetFullPath(htmlFilePath);
var fileUri = new Uri(absolutePath).AbsoluteUri;
var options = new ChromeOptions();
options.AddArgument("--headless");
using (var driver = new ChromeDriver(options))
{
driver.Navigate().GoToUrl(fileUri);
// Wait for the page to load completely
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until(d => ((IJavaScriptExecutor)d).ExecuteScript("return document.readyState").Equals("complete"));
var screenshot = ((ITakesScreenshot)driver).GetScreenshot();
screenshot.SaveAsFile(outputPath, ScreenshotImageFormat.Png);
}
}
Handling dynamic content
Modern web applications often include dynamic content that requires additional time to load. To handle such cases:
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;
public static void CaptureDynamicWebpage(string url, string outputPath)
{
var options = new ChromeOptions();
options.AddArgument("--headless");
using (var driver = new ChromeDriver(options))
{
driver.Navigate().GoToUrl(url);
// Wait for a specific element to be visible
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until(d => d.FindElement(By.Id("content-loaded")));
// Set viewport size for consistent screenshots
driver.Manage().Window.Size = new System.Drawing.Size(1920, 1080);
var screenshot = ((ITakesScreenshot)driver).GetScreenshot();
screenshot.SaveAsFile(outputPath, ScreenshotImageFormat.Png);
}
}
Ensure that the By.Id("content-loaded")
matches an element in your webpage that indicates loading
is complete.
Capturing full-page screenshots
To capture the entire webpage, including content below the fold:
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;
public static void CaptureFullPage(string url, string outputPath)
{
var options = new ChromeOptions();
options.AddArgument("--headless");
options.AddArgument("--start-maximized");
using (var driver = new ChromeDriver(options))
{
driver.Navigate().GoToUrl(url);
// Set the window size to the full height of the page
var totalHeight = (long)((IJavaScriptExecutor)driver)
.ExecuteScript("return document.body.parentNode.scrollHeight");
driver.Manage().Window.Size = new System.Drawing.Size(1920, (int)totalHeight);
// Allow time for resizing
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(2));
wait.Until(d => ((IJavaScriptExecutor)d).ExecuteScript("return document.readyState").Equals("complete"));
var screenshot = ((ITakesScreenshot)driver).GetScreenshot();
screenshot.SaveAsFile(outputPath, ScreenshotImageFormat.Png);
}
}
Note that setting the window size to match the page height allows the entire page to be captured.
Managing screenshot storage
To keep your screenshots organized, implement a simple storage manager:
public class ScreenshotManager
{
private readonly string _baseDirectory;
public ScreenshotManager(string baseDirectory)
{
_baseDirectory = baseDirectory;
Directory.CreateDirectory(_baseDirectory);
}
public string SaveScreenshot(byte[] screenshotBytes, string prefix = "")
{
var fileName = $"{prefix}screenshot_{DateTime.Now:yyyyMMdd_HHmmss}.png";
var filePath = Path.Combine(_baseDirectory, fileName);
File.WriteAllBytes(filePath, screenshotBytes);
return filePath;
}
public void CleanupOldScreenshots(int daysToKeep = 7)
{
var cutoffDate = DateTime.Now.AddDays(-daysToKeep);
var files = Directory.GetFiles(_baseDirectory, "*.png");
foreach (var file in files)
{
if (File.GetCreationTime(file) < cutoffDate)
{
File.Delete(file);
}
}
}
}
Handling different screen sizes
For responsive design testing, capture screenshots at various viewport sizes:
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.IO;
public static void CaptureResponsiveScreenshots(string url, string outputDirectory)
{
var viewports = new[]
{
new { Width = 375, Height = 667, Name = "mobile" },
new { Width = 768, Height = 1024, Name = "tablet" },
new { Width = 1920, Height = 1080, Name = "desktop" }
};
var options = new ChromeOptions();
options.AddArgument("--headless");
using (var driver = new ChromeDriver(options))
{
foreach (var viewport in viewports)
{
driver.Manage().Window.Size = new System.Drawing.Size(viewport.Width, viewport.Height);
driver.Navigate().GoToUrl(url);
// Allow time for the layout to adjust
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(2));
wait.Until(d => ((IJavaScriptExecutor)d).ExecuteScript("return document.readyState").Equals("complete"));
var screenshot = ((ITakesScreenshot)driver).GetScreenshot();
var outputPath = Path.Combine(outputDirectory, $"{viewport.Name}_{DateTime.Now:yyyyMMdd_HHmmss}.png");
screenshot.SaveAsFile(outputPath, ScreenshotImageFormat.Png);
}
}
}
This approach helps ensure that your webpage renders correctly across different devices.
Alternative tools for webpage rendering
In addition to Selenium WebDriver, other open-source tools like Puppeteer Sharp and Playwright can capture webpage screenshots in .NET. These tools provide advanced features and can handle complex web applications effectively.
Conclusion
Capturing screenshots programmatically in .NET provides valuable capabilities for testing, documentation, and monitoring. The examples above demonstrate various approaches to handle different scenarios, from simple static pages to dynamic content and responsive designs.
If you need to process, convert, or manipulate these screenshots as part of your workflow, consider using Transloadit's Document Processing service for automated image processing at scale.