In Selenium Java, getScreenshotAs() only captures the viewport, and ChromeDriver has no full-page method. Below is Selenium 4 code for every common case, each file compiled and run against Wikipedia with Selenium 4.51 and headless Chrome, plus the two output bugs we measured and how to fix them.
Add one dependency. Since Selenium 4.6, Selenium Manager downloads a matching chromedriver (and Chrome if needed), so you don't install a driver yourself.
<!-- pom.xml -->
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.51.0</version>
</dependency>
// Basic.java, run with: mvn -q compile exec:java -Dexec.mainClass=Basic
import java.nio.file.*;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.*;
public class Basic {
public static void main(String[] args) throws Exception {
ChromeOptions options = new ChromeOptions();
options.addArguments("--headless=new", "--window-size=1280,800");
WebDriver driver = new ChromeDriver(options);
try {
driver.get("https://example.com");
Path tmp = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE).toPath();
Files.copy(tmp, Path.of("viewport.png"), StandardCopyOption.REPLACE_EXISTING);
} finally {
driver.quit();
}
}
}
Measured: with --window-size=1280,800 this saved a 1280×657 PNG, not 1280×800, because the window size includes the browser UI. For an exact viewport, use the CDP override in the next example.
ChromeDriver can't do full page by itself, but ChromeDriver.executeCdpCommand talks to the DevTools protocol: read the content size, then capture beyond the viewport with a clip. This also sets an exact 1280×800 viewport and scrolls the page first so lazy-loaded images load:
// FullPage.java, run with: mvn -q compile exec:java -Dexec.mainClass=FullPage
import java.nio.file.*;
import java.util.*;
import org.openqa.selenium.chrome.*;
public class FullPage {
public static void main(String[] args) throws Exception {
ChromeOptions options = new ChromeOptions();
options.addArguments("--headless=new", "--hide-scrollbars"); // or the PNG is 15px narrow
ChromeDriver driver = new ChromeDriver(options);
try {
// exact 1280x800 viewport (--window-size includes browser UI)
driver.executeCdpCommand("Emulation.setDeviceMetricsOverride", Map.of(
"width", 1280, "height", 800, "deviceScaleFactor", 1, "mobile", false));
driver.get("https://en.wikipedia.org/wiki/Web_scraping");
// scroll through the page so lazy-loaded images load
driver.executeScript("return (async () => {"
+ " for (let y = 0; y < document.body.scrollHeight; y += 600) {"
+ " window.scrollTo(0, y); await new Promise(r => setTimeout(r, 100)); }"
+ " window.scrollTo(0, 0); })()");
Map<String, Object> metrics = driver.executeCdpCommand("Page.getLayoutMetrics", Map.of());
@SuppressWarnings("unchecked")
Map<String, Object> size = (Map<String, Object>) metrics.get("cssContentSize");
Map<String, Object> shot = driver.executeCdpCommand("Page.captureScreenshot", Map.of(
"format", "png",
"captureBeyondViewport", true,
"clip", Map.of("x", 0, "y", 0, "width", size.get("width"),
"height", size.get("height"), "scale", 1)));
Files.write(Path.of("full.png"), Base64.getDecoder().decode((String) shot.get("data")));
} finally {
driver.quit();
}
}
}
Measured: without --hide-scrollbars the PNG came out 1265px wide instead of 1280, because cssContentSize excludes the 15px scrollbar. With it, the article was a full 1280×10474. WebDriver waits for a promise returned from executeScript, so the async scroll finishes before the capture. executeCdpCommand exists only on Chromium drivers (Chrome, Edge), so declare the variable as ChromeDriver, not WebDriver.
geckodriver supports it natively: ((HasFullPageScreenshot) driver).getFullPageScreenshotAs(OutputType.FILE) on a FirefoxDriver. We checked the interface in the 4.51 jar but didn't run Firefox for this guide.
// Element.java, run with: mvn -q compile exec:java -Dexec.mainClass=Element
import java.nio.file.*;
import java.time.Duration;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.*;
import org.openqa.selenium.support.ui.*;
public class Element {
public static void main(String[] args) throws Exception {
ChromeOptions options = new ChromeOptions();
options.addArguments("--headless=new", "--window-size=1280,800");
WebDriver driver = new ChromeDriver(options);
try {
driver.get("https://en.wikipedia.org/wiki/Web_scraping");
WebElement box = new WebDriverWait(driver, Duration.ofSeconds(10))
.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("h1")));
Path tmp = box.getScreenshotAs(OutputType.FILE).toPath();
Files.copy(tmp, Path.of("element.png"), StandardCopyOption.REPLACE_EXISTING);
} finally {
driver.quit();
}
}
}
Wait for visibility first: findElement straight after get() races with client-side rendering. WebElement.getScreenshotAs crops to the element's box (the Wikipedia h1 came out 592×40), but only the part inside the viewport, so for tall elements use the CDP clip from the full-page example with the element's getRect(), or see the element screenshot guide.
// PrintPdf.java, run with: mvn -q compile exec:java -Dexec.mainClass=PrintPdf
import java.nio.file.*;
import java.util.Base64;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.*;
import org.openqa.selenium.print.*;
public class PrintPdf {
public static void main(String[] args) throws Exception {
ChromeOptions options = new ChromeOptions();
options.addArguments("--headless=new");
WebDriver driver = new ChromeDriver(options);
try {
driver.get("https://en.wikipedia.org/wiki/Web_scraping");
PrintOptions print = new PrintOptions();
print.setPageSize(PageSize.ISO_A4); // the default is US Letter
print.setPageMargin(new PageMargin(1, 1, 1, 1)); // top, bottom, left, right in cm
print.setBackground(true); // keep background colours and images
Pdf pdf = ((PrintsPage) driver).print(print);
Files.write(Path.of("page.pdf"), Base64.getDecoder().decode(pdf.getContent()));
} finally {
driver.quit();
}
}
}
This printed the article as 10 A4 pages. PageSize and PageMargin are in centimetres, and printing uses the page's @media print CSS. Without setBackground(true) background colours and images are dropped.
--window-size includes browser UI. Use Emulation.setDeviceMetricsOverride as above.--hide-scrollbars."deviceScaleFactor", 2 in the override.driver.executeScript("const s = document.createElement('style'); s.textContent = '#onetrust-banner-sdk, .cookie-banner { display: none !important }'; document.head.appendChild(s)"). Careful if you also undo scroll locks: setting overflow: auto on both html and body turns the body into its own scroller on pages with body { height: 100% } (Wikipedia), and a full-page capture shrinks to the viewport. Unlock with html { overflow: auto } body { overflow: visible }. Our own API had this exact bug until 2026-10-22.SessionNotCreatedException in Docker or CI: add --no-sandbox and --disable-dev-shm-usage (only in containers you trust).apt install fonts-noto-cjk fonts-noto-color-emoji."format", "jpeg", "quality", 80 in the CDP call.If screenshots are a side feature, you may not want Chrome, a driver and fonts in your deployment. Shotmint runs the browser, scrolls for lazy images and hides cookie banners. Plain JDK 11+ HttpClient, no dependencies:
// ApiShot.java, run with: SHOTMINT_KEY=... java ApiShot.java
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.time.Duration;
public class ApiShot {
public static void main(String[] args) throws Exception {
String target = URLEncoder.encode("https://en.wikipedia.org/wiki/Web_scraping", StandardCharsets.UTF_8);
HttpRequest req = HttpRequest.newBuilder(URI.create("https://shotmint.creasework.com/v1/screenshot?url=" + target
+ "&full_page=true&device_scale_factor=2&format=jpeg&quality=80&block_ads=true"))
.header("X-API-Key", System.getenv("SHOTMINT_KEY"))
.timeout(Duration.ofSeconds(90))
.build();
HttpResponse<Path> res = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofFile(Path.of("full.jpg")));
if (res.statusCode() != 200) throw new RuntimeException("Shotmint error " + res.statusCode());
}
}
This returned a 2560×20948 JPEG of the same article in about 2.5 s. Spring Boot and PDF examples: Java screenshot API guide, HTML to PDF in Java.
| Selenium Java | Shotmint |
|---|---|
getScreenshotAs(OutputType.FILE) | GET /v1/screenshot?url=… |
CDP captureBeyondViewport | full_page=true |
WebElement.getScreenshotAs | selector=h1 |
setDeviceMetricsOverride | width, height, device_scale_factor |
Injected display: none CSS | hide_selectors or block_ads=true |
((PrintsPage) driver).print() | /v1/pdf with format=A4, margin |
Keep it for browser automation and tests: logins, click-through flows, forms, cross-browser checks. The API is for when you only need the image or PDF of a URL or some HTML. Python version: Selenium screenshots in Python. No code at all: the full-page screenshot tool.
No signup, no card. Get a key in one click, then buy credits only if you need more (from €5 for 2,000, never expire). From a script, an AI agent, Make or Zapier, POST /v1/keys/free (no body) returns a key as JSON (openapi.json, no-code recipes).
All guides: guides · integrations · comparisons