Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use Java’s ProcessBuilder to launch the separately installed wkhtmltoimage executable. Pass the executable, each option, the input URL or HTML file, and an output image as separate list items; wait for completion, capture diagnostics, enforce a timeout, and verify the exit code and output file. This is the supported practical route because the Java wrapper projects commonly found online target wkhtmltopdf, not the image converter.

What wkhtmltoimage is—and what Java must provide

wkhtmltoimage is a command-line HTML-to-image converter built on Qt WebKit. It accepts a URL or local HTML document and writes an image such as PNG, JPEG, or WebP. It is not a Java library: your application needs a compatible executable on the host (or in its container), permission to run it, and any libraries required by that binary.

The upstream repository has been archived read-only since January 2, 2023. That does not by itself establish a vulnerability, but it does mean you should review browser compatibility, binary availability, and security policy before choosing it for a new service. Treat the executable as an external dependency and pin the exact binary you deploy.

Install and verify the executable

  1. Install a platform-appropriate wkhtmltoimage binary using your operating-system package process or a release artifact you have vetted.
  2. Place it at a known path, for example /usr/local/bin/wkhtmltoimage on Linux or an absolute path under your application installation on Windows.
  3. From the same account that will run Java, execute wkhtmltoimage --version. A version response confirms that the file is executable and its dependent libraries can load.
  4. Capture the absolute path in configuration rather than relying on a developer’s PATH. In containers, include the binary and required shared libraries in the image and run as a non-privileged user.

Do not download a binary from an untrusted URL at application start. Validate checksums in your build or deployment pipeline, and isolate conversion if untrusted pages are processed.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The basic Java implementation

ProcessBuilder takes a command list. Keep flags and values as separate elements; this avoids shell quoting differences and prevents user-supplied URLs from becoming shell syntax.

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.List;
import java.util.concurrent.TimeUnit;

public final class WkhtmlToImage {
    public static void capture(String executable, String input, Path output)
            throws IOException, InterruptedException {
        List<String> command = List.of(
                executable,
                "--format", "png",
                "--width", "1200",
                input,
                output.toAbsolutePath().toString()
        );

        Process process = new ProcessBuilder(command)
                .redirectError(ProcessBuilder.Redirect.INHERIT)
                .redirectOutput(ProcessBuilder.Redirect.DISCARD)
                .start();

        boolean finished = process.waitFor(90, TimeUnit.SECONDS);
        if (!finished) {
            process.destroy();
            if (!process.waitFor(5, TimeUnit.SECONDS)) {
                process.destroyForcibly();
            }
            throw new IOException("wkhtmltoimage timed out");
        }
        if (process.exitValue() != 0) {
            throw new IOException("wkhtmltoimage exited with code " + process.exitValue());
        }
        if (!Files.isRegularFile(output) || Files.size(output) == 0) {
            throw new IOException("No image was produced: " + output);
        }
    }

    public static void main(String[] args) throws Exception {
        capture("/usr/local/bin/wkhtmltoimage",
                "https://example.com", Path.of("output.png"));
    }
}

Replace the executable path and input with values from your deployment. The final two operands are the input and output; the manual’s command shape is wkhtmltoimage [OPTIONS]... <input file> <output file>. A URL can be the input operand, as in the example, or you can pass a local HTML path.

Capture stderr instead of inheriting it

For a web service, redirecting diagnostics to a bounded log is usually preferable to printing directly to the parent process. If you read a stream yourself, consume it while the process runs; otherwise a full pipe can block the child. Java’s redirectError and related process APIs support either inherited, file, or pipe-based handling.

Useful options for real pages

Format, quality, and dimensions

Use --format png, --format jpg, or another format supported by the installed build. --quality controls lossy output where applicable. --width supplies a screen-width guide; it is not automatically a strict crop. The manual describes smart-width behavior, so test the combination of width, height, crop controls, and zoom against your target pages. Default height is calculated from page content.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
List<String> command = List.of(
    executable,
    "--format", "jpg",
    "--quality", "85",
    "--width", "1440",
    "--height", "900",
    "--zoom", "1.0",
    input,
    output.toString()
);

JavaScript and render timing

JavaScript is enabled by default in the normal command-line workflow, but you can state intent with --enable-javascript or disable it with --disable-javascript. For applications that render asynchronously, use --javascript-delay <milliseconds>, --window-status <value>, or --run-script <script> as appropriate. A delay increases every capture’s latency, so use the smallest value that reliably produces the required state.

Local HTML and asset access

For a local document that references images, stylesheets, or fonts, local-file policy determines whether those resources load. --disable-local-file-access blocks local access; --allow <path> explicitly permits a directory. Prefer narrowly scoped allowed directories over broad access, especially when the HTML or its asset paths are influenced by users.

Headers, cookies, proxies, and load failures

The command supports custom headers, cookies, proxy configuration, and load-error handling options. Use them for authenticated or network-dependent pages, but keep credentials out of command-line logs where possible. A timeout or load-error policy should match your application: fail fast for interactive requests, or record a failed job for later inspection in batch processing.

Production process handling

  • Timeouts: set an upper bound with waitFor(timeout, unit); terminate gracefully, then forcibly if necessary.
  • Concurrency: limit simultaneous child processes. Each conversion consumes CPU, memory, and file descriptors; an unbounded queue can exhaust the host.
  • Temporary files: write to a per-job directory, use non-predictable names, and delete inputs and outputs according to your retention policy.
  • Output validation: check exit status, file existence, non-zero length, and (if required) image decoding before returning success.
  • Network safety: restrict destinations or use an egress proxy when users can submit URLs. A renderer that fetches arbitrary URLs can reach internal services unless your network policy prevents it.
  • Observability: log duration, exit code, selected non-secret options, and a correlation ID. Avoid logging cookies, authorization headers, or complete HTML containing personal data.

Why common Java wrappers do not solve image capture

Repositories and Maven artifacts such as com.github.jhonnymertz:java-wkhtmltopdf-wrapper:1.3.1-RELEASE describe wrappers around wkhtmltopdf, the PDF command. Their classes and examples should not be pasted into an image tutorial: PDF output and image output are different executables and option surfaces. Unless a library explicitly documents wkhtmltoimage support, invoke the executable directly.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Native C binding: an alternative integration path

The project documents a C binding for the image converter and describes a lifecycle of initialization, global settings, converter creation, callbacks, conversion, and destruction. Java can reach such an API through JNI, JNA, or another native-interop layer, but you then own native library packaging, ABI compatibility, memory and callback safety, and platform-specific testing. Choose this route only when in-process native integration justifies that operational cost. The CLI gives clearer process isolation and simpler deployment at the expense of a child process.

Troubleshooting wkhtmltoimage from Java

“Cannot run program” or error 2

The path is wrong, the file is not executable, or a dynamic dependency is missing. Print the configured absolute path, run it as the Java service account, and verify --version outside Java.

Exit code is non-zero and no image exists

Run the same argument list manually with stderr visible. Check URL reachability, TLS or proxy requirements, malformed options, and input/output permissions. Do not collapse diagnostics into a generic “conversion failed” message.

The page is blank or assets are missing

Confirm that JavaScript has enough time, then test a small --javascript-delay or a page-specific --window-status. For local HTML, inspect --disable-local-file-access and add only the required directory with --allow. Network resources may also require headers, cookies, or a proxy.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The screenshot is the wrong size

Remember that --width is generally a screen-width guide, not a guaranteed crop. Test height, crop options, zoom, and smart-width behavior together. Pages with responsive breakpoints may select a different layout at a different width.

The Java request hangs

A renderer can wait on page scripts, network resources, or an unconsumed error stream. Consume or redirect both process streams, enforce a timeout, and destroy the process on expiry. Record the URL and job ID so the failing page can be reproduced safely.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

If you need a screenshot service rather than a locally managed Qt WebKit process, ScreenshotNeo accepts one GET request and returns PNG, JPEG, WebP, or PDF. Before capture it accepts cookie/consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers report the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients.

Example using the documented API pattern (see the ScreenshotNeo documentation):

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

Every plan includes the same feature set: full-page and selector captures, device and retina settings, dark mode, PDF controls, custom CSS and JavaScript, clicks and waits, request blocking, headers, cookies, user agent, authorization, timezone, geolocation, transparent backgrounds, resizing, configurable caching, signed links, asynchronous webhooks, bulk capture for 100 URLs per call, usage reporting, and an OpenAPI specification. The free plan includes 1,000 screenshots each month with no card; paid plans start at $5 for 3,000. Create a free ScreenshotNeo account.

Choosing between the CLI and a service

Requirement ProcessBuilder plus wkhtmltoimage ScreenshotNeo
Deployment You package and patch a native executable and its libraries. Call an HTTPS endpoint; no browser binary on your host.
Rendering stack Qt WebKit supplied by the archived project. Hosted screenshot API with configurable capture controls.
Failure billing Your infrastructure bears process and retry costs. Failed loads, blank pages, bot checks, timeouts, and cache hits are not billed.
AI-agent workflow Requires your own integration. MCP tools are provided.
Cost entry point Infrastructure and binary-management costs are yours. 1,000 monthly shots free; paid plans start at $5 for 3,000.

Frequently Asked Questions

Can ProcessBuilder execute a URL directly?

Yes. Supply the URL as the input operand in the argument list; no shell is required.

Do I need wkhtmltopdf installed as well?

No. Image capture requires the separate wkhtmltoimage executable. PDF wrapper libraries do not provide that executable.

Is wkhtmltoimage actively maintained?

Its upstream repository is archived read-only since January 2, 2023. Evaluate compatibility and security policy before adoption.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.