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.

Direct answer: Install the Python imgkit wrapper and a compatible wkhtmltoimage executable, then call imgkit.from_string, imgkit.from_file, or imgkit.from_url. Give the call an output filename such as out.png, or pass False to receive image bytes in memory. IMGKit passes rendering options to wkhtmltoimage, so your result depends on the binary you install, its Qt build, and whether your environment has a display.

What IMGKit and wkhtmltoimage do

IMGKit is a Python interface; it does not render HTML by itself. It starts the separate wkhtmltoimage command-line program, supplies your HTML and options, and returns the generated image or writes it to disk. This separation matters when deploying: pip install imgkit installs the wrapper, but you must install the executable separately and make it discoverable.

The workflow is useful for HTML strings, local files, and public URLs. It is a desktop-friendly approach, but older WebKit rendering and binary packaging can make modern JavaScript-heavy pages behave differently from a current browser.

Install the Python package and renderer

Install IMGKit

  1. Create or activate a virtual environment for the project.
  2. Run pip install imgkit.
  3. Install a compatible wkhtmltoimage binary for your operating system. The executable is distributed separately from IMGKit.

On Debian or Ubuntu, the IMGKit documentation describes installation with apt-get. macOS users can use Homebrew, while Windows and other platforms use the available binary installers. Distribution packages on Debian and Ubuntu may be built without the upstream wkhtmltopdf Qt patches; those builds can have reduced functionality. If an option you need does not work, try a static upstream binary and verify its behavior in your target environment.

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.

Verify executable discovery

Check that the shell can find the binary before debugging Python:

  • Linux or macOS: which wkhtmltoimage
  • Windows: where wkhtmltoimage

If neither command returns a path, install the binary or add its directory to PATH. You can also configure an explicit path in Python, which is safer for a service with a fixed deployment layout.

Convert an HTML string, file, or URL

HTML string to PNG

import imgkit

html = """


  
    
    
  
  

Hello from HTML

This becomes a PNG.

""" imgkit.from_string(html, "out.png")

The output filename determines the ordinary file workflow. Use an extension that matches the format you request or expect, such as .png or .jpg.

Local HTML file to JPEG

import imgkit

imgkit.from_file("test.html", "out.jpg")

Relative assets in a local document must be readable by the renderer. Use correct file URLs or paths and confirm that the process has permission to read the HTML, stylesheets, fonts, and images.

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

Remote page to an image

import imgkit

imgkit.from_url("https://example.com", "out.png")

The renderer must be able to resolve DNS, connect to the site, and fetch every required resource. A URL that works in your interactive browser can still fail in a server environment because of firewall rules, authentication, TLS differences, or JavaScript incompatibility.

Keep the image in memory

import imgkit

image_bytes = imgkit.from_url("https://example.com", False)
# image_bytes is suitable for an HTTP response, object storage upload, or database field.

Passing False instead of a filename returns the generated image data. This avoids a temporary file when your application immediately streams or uploads the result.

Control format, cropping, CSS, cookies, and headers

Pass wkhtmltoimage options

IMGKit accepts an options dictionary. Use option names without the leading two hyphens used on the command line. Values represent the command-line value; flag-only switches can be enabled with a value such as None.

import imgkit

options = {
    "format": "png",
    "encoding": "UTF-8",
    "crop-w": 1200,
    "crop-h": 800,
    "crop-x": 0,
    "crop-y": 0,
    "no-outline": None,
    "quiet": None,
}

imgkit.from_string("<h1>Cropped output</h1>", "cropped.png", options=options)

Cropping is useful when a page has a known coordinate region. It is not a substitute for responsive layout: choose a viewport and page design that produce the dimensions you need, then crop only when the bounds are predictable.

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

Attach one or more stylesheets

import imgkit

html = "<main class='card'><h1>Invoice</h1></main>"
imgkit.from_string(
    html,
    "invoice.png",
    css=["base.css", "print.css"]
)

For local HTML or strings, css can be one stylesheet path or a list. Keep paths stable in deployment and make sure the renderer can read them.

Send cookies and custom headers

import imgkit

options = {
    "cookie": ["session_id", "abc123"],
    "custom-header": ["X-Render-Mode", "image"],
}
imgkit.from_url("https://example.com/account", "account.png", options=options)

Cookies and custom headers are repeatable wkhtmltoimage options. Use them only for data your application is authorized to access, and avoid logging session values in command output or exception traces.

Embed settings in HTML meta tags

IMGKit also recognizes settings in document metadata. For example:

<meta name="imgkit-format" content="png">
<meta name="imgkit-orientation" content="Landscape">

Meta settings are convenient for templates that carry their own rendering defaults. Keep operational settings such as credentials and executable paths outside user-controlled HTML.

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

Run IMGKit on a headless Linux server

Some wkhtmltoimage builds expect an X display even when no physical desktop is present. Install Xvfb on Ubuntu with:

sudo apt-get install xvfb

Then configure IMGKit to use the xvfb-run wrapper when your binary requires it:

import imgkit

config = imgkit.config(
    wkhtmltoimage="/opt/bin/wkhtmltoimage",
    xvfb="/opt/bin/xvfb-run",
)

imgkit.from_string(
    "<h1>Headless render</h1>",
    "output.png",
    config=config,
)

Use absolute paths in containers and service units so a different PATH does not change behavior. Test the exact image, fonts, and network permissions under the same user that will run production jobs.

Build a reusable conversion function

A small wrapper gives every call the same encoding, timeout-related policy, and output handling. IMGKit delegates process execution to wkhtmltoimage, so catch exceptions and retain the command diagnostics during development.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
from pathlib import Path
from typing import Optional, Union
import imgkit


def html_to_image(
    html: str,
    output: Optional[Union[str, Path]] = None,
) -> bytes:
    options = {
        "format": "png",
        "encoding": "UTF-8",
        "quiet": None,
    }
    target = str(output) if output is not None else False
    result = imgkit.from_string(html, target, options=options)
    if output is not None:
        return Path(output).read_bytes()
    return result


png_data = html_to_image("<p>Generated</p>")
Path("generated.png").write_bytes(png_data)

For a high-volume service, isolate rendering workers, cap input size, validate URLs, and prevent untrusted HTML from reaching internal network addresses. A renderer that can fetch arbitrary URLs can become a server-side request-forgery risk if its input is user-controlled.

Why common conversions fail

“wkhtmltoimage is missing”

Cause: only the Python package was installed, the executable is not on PATH, or the process runs with a different environment than your shell.

Fix: run which wkhtmltoimage or where wkhtmltoimage, install the binary, then pass its absolute location with imgkit.config(wkhtmltoimage="/absolute/path/wkhtmltoimage").

Rendering works locally but not in production

Cause: a headless host lacks a display, fonts, outbound network access, or permission to read local assets.

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

Fix: install and configure Xvfb where required, package the fonts and stylesheets, test as the service user, and verify DNS/TLS access from the server.

Options are ignored or an option causes a crash

Cause: the installed distribution build may lack Qt patches or may not support the flag. Some versions also report segmentation faults.

Fix: run the command printed in the IMGKit exception directly; its diagnostics usually identify the unsupported flag or missing resource. Confirm the binary version and try a static upstream build when the package build has reduced functionality.

The page is blank or incomplete

Cause: the page depends on JavaScript, delayed network calls, blocked resources, authentication, or browser features that the older renderer does not implement.

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

Fix: first save a minimal static HTML test. Then check URLs, cookies, headers, and stylesheet paths. If the page fundamentally requires a modern browser runtime, use a browser-based capture service rather than adding increasingly fragile workarounds.

Output is the wrong size or format

Cause: page dimensions, cropping flags, orientation metadata, and file extension do not agree.

Fix: set format explicitly, define crop dimensions only when needed, and inspect the resulting image dimensions in an automated test.

Performance, reliability, and operational choices

  • Warm workers: keep a controlled worker process available if startup cost matters, but recycle workers if repeated jobs expose memory growth.
  • Bound work: limit HTML size, remote resource count, and concurrent conversions. A page that waits on many third-party assets can consume a worker for a long time.
  • Cache deliberately: cache by a hash of HTML, CSS, options, and relevant input data. Include cookies or authenticated content in the key, or you may serve one user’s image to another.
  • Observe failures: record exit status, renderer stderr, elapsed time, output byte count, and the binary version. Do not record secrets from cookies or authorization headers.
  • Test representative pages: include local assets, remote assets, long pages, non-Latin text, and pages that require authentication. The IMGKit package version listed on PyPI is 1.0.5, released March 13, 2021, so verify compatibility and maintenance before adopting it for a new production system.

There is no published benchmark or success-rate statistic in the available documentation. Measure your own pages and infrastructure instead of treating a single local result as a reliability guarantee.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
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 an API rather than a local renderer, ScreenshotNeo takes one GET request and returns a PNG, JPEG, WebP, or PDF. It accepts the cookie or consent banner like a visitor, then removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each cleanup step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status.

Use the same request from any language:

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}`);

See the ScreenshotNeo documentation for request parameters. It also provides an MCP server with take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. Options cover full-page capture with lazy images loaded, CSS-selector element capture, dark mode, 12 device presets or custom viewports, retina scale, PDF paper settings and page ranges, custom CSS and JavaScript, clicks, selector or network-idle waits, ad/tracker/request blocking, headers, cookies, user agents, authorization, timezone, geolocation, transparent backgrounds, resizing, chosen cache TTLs, signed image links, asynchronous webhooks, 100-URL bulk calls, usage data, and an OpenAPI specification.

The Free plan includes 1,000 screenshots each month with no card. Paid plans start at $5 for 3,000 shots; yearly billing gives two months free, and every feature is included on every plan. Create a free ScreenshotNeo account.

IMGKit versus a hosted screenshot API

Requirement IMGKit and wkhtmltoimage ScreenshotNeo
Where rendering runs Your Python process and installed binary Hosted HTTP API
Input forms HTML string, local file, or URL URL plus capture options; also supports HTML/CSS-to-image
Deployment work Install and maintain the binary, fonts, and possibly Xvfb Send an authenticated request
Popup and consent cleanup Must be implemented or hidden by your HTML/options Consent banners, newsletter popups, and chat widgets are removed before capture
Billing on failed pages Your infrastructure still spends worker time Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing
AI-agent integration Build your own integration MCP server tools are available

FAQ

Can IMGKit create a PDF?

IMGKit is the image wrapper around wkhtmltoimage. For PDF output, use the wkhtmltopdf tool or a service that explicitly supports PDF capture, such as ScreenshotNeo’s capture_pdf tool.

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

Does IMGKit install wkhtmltoimage automatically?

No. pip install imgkit installs the Python wrapper; install and maintain the executable separately.

Should I use a system package or a static binary?

Start with your platform’s supported package, but verify required features. Debian and Ubuntu packages may omit Qt patches, so a static upstream binary can be necessary for advanced rendering.

How can I return an image from a web endpoint?

Call an IMGKit function with False, set the response content type to the selected image format, and stream the returned bytes. Do not write temporary files unless your framework or storage layer requires them.

Frequently Asked Questions

Can IMGKit create a PDF?

IMGKit wraps wkhtmltoimage for image output. Use wkhtmltopdf or a PDF-capable service for PDF files.

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

Does IMGKit install wkhtmltoimage automatically?

No. The executable must be installed separately.

Should I use a system package or a static binary?

Verify the features you need; a static upstream binary may be required when a distribution package lacks Qt patches.

How can I return an image from a web endpoint?

Pass False as the output target, then stream the returned bytes with the correct image content type.

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.