Driver FixRecommendedSound, Wi-Fi or graphics acting up? Check drivers firstFind missing or outdated drivers fast.Check DriversOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix Now×
Skip to content
browser automation

How to Screenshot a Webpage as a PNG in Ruby with Ferrum

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

The shortest Ruby workflow is Ferrum: launch Chrome or Chromium, navigate to the URL, save a PNG, and quit the browser.

require "ferrum"

browser = Ferrum::Browser.new
browser.go_to("https://example.com")
browser.screenshot(path: "page.png")
browser.quit

Ferrum runs headless by default. You need Ruby, the ferrum gem, and a Chrome or Chromium executable; installing the gem does not install the browser.

Install Ferrum and its browser dependency

Add Ferrum to your application’s Gemfile:

gem "ferrum"

Then install the bundle:

bundle install

Make Chrome or Chromium available on PATH. Ferrum can also use a browser path supplied through BROWSER_PATH or a browser-path option when your executable is installed elsewhere. Use the browser vendor’s or Chromium project’s current installation instructions for your operating system.

A standalone Ruby script

Create screenshot.rb with the direct workflow:

require "ferrum"

browser = Ferrum::Browser.new
begin
  browser.go_to("https://example.com")
  browser.screenshot(path: "page.png")
ensure
  browser.quit
end

The ensure block closes Chrome even when navigation or capture raises an exception. After the script finishes, page.png is written in the current directory. Ferrum’s default screenshot format is PNG.

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

Viewport and full-page PNGs

Without additional options, Ferrum captures the current browser viewport. To capture the entire document, pass full: true:

require "ferrum"

browser = Ferrum::Browser.new
begin
  browser.go_to("https://example.com/docs")
  browser.screenshot(path: "docs-full.png", full: true)
ensure
  browser.quit
end

Full-page mode is useful for long articles, documentation and landing pages. It is not the same as a viewport image: a very tall page can produce a large bitmap and may expose layout or lazy-loading behavior that is not visible in the initial viewport.

Set a predictable viewport

Set the browser window or viewport dimensions before navigation when responsive layout must be repeatable. A fixed size prevents a desktop capture from becoming a mobile capture because the script runs on a different machine. In a test suite, Cuprite’s documented driver setup accepts a window_size such as [1200, 800].

Capture one element or a rectangle

Ferrum’s screenshot API accepts a CSS selector for an element crop:

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

browser = Ferrum::Browser.new
begin
  browser.go_to("https://example.com")
  browser.screenshot(path: "article.png", selector: "main article")
ensure
  browser.quit
end

For a coordinate rectangle, use area:

browser.screenshot(
  path: "top-left.png",
  area: { x: 0, y: 0, width: 800, height: 600 }
)

Use scale: when you need a different pixel density, and background_color: when the output should have a specific background. Without a path, Ferrum returns encoded image data instead of writing a file, which is useful when an upload client or another processing step consumes the bytes.

Important option interactions

  • full: true takes precedence over cropping: selector and area options are ignored in full-page mode.
  • If both selector and area are supplied, the selector takes precedence.
  • Choose one capture intent—full document, element, or rectangle—rather than combining incompatible options.

Wait for the page state you actually need

A navigation completing does not guarantee that a single-page application, chart or lazy image is ready for the screenshot. Decide what “ready” means for your page and wait for that condition before calling screenshot. For example, your application may need a known selector to appear, a JavaScript state transition, or a short delay after an animation. The correct wait is application-specific; there is no universal delay that works for every site.

For full-page captures, verify that content loaded below the fold is present. If the site lazy-loads images only when they enter a viewport, scroll or trigger the application’s own loading mechanism before capture, then confirm the resulting document state.

Save files safely in automation

Use unique paths

Parallel jobs can overwrite the same filename. Include a record ID, timestamp or job UUID in the output path, and create the destination directory before starting the browser. Keep the extension as .png so downstream tooling and humans can identify the format.

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

Close every browser

One browser process per job can consume substantial memory if it is left running. Wrap the capture in begin … ensure … end, or put browser ownership in a service object that always calls quit.

Check the result

After capture, verify that the file exists and is non-empty before marking the job successful. A successful HTTP navigation can still lead to a login page, an error document or a bot-check screen, all of which are valid browser images but incorrect business output.

Use Ferrum through Capybara with Cuprite

If the screenshot belongs in an existing Capybara JavaScript test suite, Cuprite is the relevant Ruby driver. It is built on Ferrum and exposes browser functionality through Capybara.

require "capybara/cuprite"

Capybara.javascript_driver = :cuprite
Capybara.register_driver(:cuprite) do |app|
  Capybara::Cuprite::Driver.new(app, window_size: [1200, 800])
end

Within a Capybara test, Cuprite provides Ferrum-backed operations. Its driver API includes page.driver.render_base64(format, options) for Base64 screenshot output. Check the current Cuprite documentation for driver-specific method names and options, because a test driver’s lifecycle and configuration differ from a one-off Ferrum script.

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

When to choose which

Need Use
One script or a background job that controls Chrome directly Ferrum
Screenshot assertions or artifacts inside a Capybara JavaScript suite Cuprite
Viewport image Leave full unset
Entire document Pass full: true
File on disk Pass path: "name.png"
Encoded data for another service Omit path and handle the returned data

Docker and deployment considerations

Headless Chrome in a container still needs a compatible browser binary and the libraries it requires. Cuprite’s setup documentation calls out a no-sandbox browser option for Docker examples. Apply that setting only with an understanding of your container’s security model, and verify it against current Chrome, Chromium and Cuprite guidance. A local script that works on a developer laptop can fail in a minimal image because the executable, fonts or shared libraries are missing.

Troubleshooting Ruby webpage screenshots

Ferrum cannot find Chrome or Chromium

Cause: no supported browser is installed, or it is not on PATH. Fix: install Chrome or Chromium, confirm the executable is discoverable, or set BROWSER_PATH or Ferrum’s browser-path option to the absolute executable path.

The script exits with a connection or launch error

Cause: the browser failed to start, often because of an incompatible executable, missing container libraries or an unsuitable sandbox configuration. Fix: run the same browser binary manually, confirm its version and dependencies, and review the deployment’s sandbox settings.

The PNG shows a loading spinner or empty component

Cause: capture happened before client-side rendering or data loading finished. Fix: wait for a page-specific selector or state, and ensure lazy content has been triggered before the screenshot call.

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

The image is mobile-sized or differs between runs

Cause: viewport dimensions changed, or responsive code reacted to a different user agent or device profile. Fix: configure a fixed window size and keep browser configuration consistent across workers.

A full-page capture is missing images

Cause: images are lazy-loaded only after scrolling or depend on later network activity. Fix: cause the page to load those resources, wait for the application’s completion signal, then capture with full: true.

The crop is not the one requested

Cause: full-page mode ignores selector and area, and selector takes precedence over area. Fix: remove full: true for a crop and pass only the crop option you intend to use.

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

Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server. One GET request returns a PNG, JPEG, WebP or PDF, so Ruby code does not need to manage a local Chrome process.

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

For Ruby, the API call can be made with Net::HTTP or any HTTP client. The equivalent cURL command is:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Ruby example:

require "net/http"
require "uri"

uri = URI("https://api.screenshotneo.com/v1/shot")
uri.query = URI.encode_www_form(
  access_key: "YOUR_API_KEY",
  url: "https://stripe.com"
)
response = Net::HTTP.get_response(uri)
raise "Screenshot failed: #{response.code}" unless response.is_a?(Net::HTTPSuccess)
File.binwrite("shot.webp", response.body)

See the ScreenshotNeo API documentation for request parameters and response headers. The service supports full-page capture, CSS-selector elements, dark mode, device presets, arbitrary viewports, retina scale, PDF settings, custom CSS and JavaScript, clicks, selector or network-idle waits, request blocking, headers, cookies, user agents, timezone, geolocation, transparent backgrounds, resizing, chosen cache TTLs, signed image links, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, usage information and an OpenAPI specification. Parameter names used by other screenshot APIs also work, which can simplify migration.

Its cleanup step accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups and chat widgets; each step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads and cache hits cost nothing, and response headers identify the page verdict and whether the request was billed. An MCP server provides take_screenshot, get_page_info and capture_pdf tools for Claude, Cursor and other MCP clients.

The Free plan includes 1,000 shots per month without a card. Paid plans start at $5 for 3,000 shots; yearly billing provides two months free, and every feature is available on every plan. Create a free ScreenshotNeo account to get started.

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.

Cost, reliability and workflow choices

  • Ferrum: no screenshot-service charge, but you operate Chrome, its dependencies, concurrency and cleanup. It is a strong fit when the browser must run inside your own network or test process.
  • Cuprite: keeps screenshots in the Capybara test lifecycle and avoids building a separate automation layer.
  • ScreenshotNeo: moves browser maintenance and capture delivery to an API, adds verdict and billing headers, and supports asynchronous and bulk requests when a local browser fleet is unnecessary.

Whichever path you choose, make readiness explicit, fix viewport settings, preserve the response or file, and log the URL, options and failure reason so an incorrect image can be reproduced.

Frequently Asked Questions

Does Ferrum install Chrome for me?

No. The gem requires a Chrome or Chromium browser executable supplied separately through PATH, BROWSER_PATH or a configured browser path.

How do I return PNG bytes instead of saving a file?

Call Ferrum’s screenshot method without path:. It returns encoded image data that your Ruby code can upload or process.

Can I combine full-page mode with selector cropping?

No. full: true ignores selector and area. Remove full for a crop, and remember that selector takes precedence over area.

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

Is Cuprite a replacement for Ferrum?

Cuprite is the Capybara driver built on Ferrum. Use it when the capture belongs in a Capybara JavaScript test suite; use Ferrum directly for a standalone browser script.

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.

Leave a Reply

Your email address will not be published. Required fields are marked *

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

Read next

Recommended PC Tool
Recommended PC Tool
Crashes, No Sound, or Screen Glitches?Free driver scan
PC Slower Than It Used to Be?Free scan - under a minute

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.