cdp-html-shot

Crates.iocdp-html-shot
lib.rscdp-html-shot
version0.2.4
created_at2024-10-30 16:58:07.256576+00
updated_at2025-12-08 09:00:11.489566+00
descriptionA Rust library for capturing HTML screenshots using CDP.
homepage
repositoryhttps://github.com/araea/cdp-html-shot
max_upload_size
id1428839
size149,354
nawyjx (araea)

documentation

https://docs.rs/cdp-html-shot

README

cdp-html-shot

github crates.io docs.rs

A high-performance Rust library for capturing HTML screenshots using the Chrome DevTools Protocol (CDP).

  • Robust: Automatic cleanup of browser processes and temporary files (RAII).
  • Fast: Asynchronous API built on tokio and WebSockets.
  • Precise: Capture screenshots of specific DOM elements via CSS selectors.
  • HiDPI Support: Control deviceScaleFactor for crystal-clear, high-resolution images.
  • Flexible: Full control over viewport, image format, quality, and more.

Installation

Add this to your Cargo.toml:

[dependencies]
cdp-html-shot = "0.2"

Examples

Quick Capture

Render HTML strings and capture specific elements instantly.

use anyhow::Result;
use base64::Engine;
use cdp_html_shot::Browser;

#[tokio::main]
async fn main() -> Result<()> {
    let html = r#"
        <html>
            <body>
                <h1 id="title">Hello, CDP!</h1>
            </body>
        </html>
    "#;

    // Launch headless browser
    let browser = Browser::new().await?;

    // Render and capture the <h1> element
    let base64_image = browser.capture_html(html, "#title").await?;

    // Decode and save
    let img_data = base64::prelude::BASE64_STANDARD.decode(base64_image)?;
    std::fs::write("screenshot.jpeg", img_data)?;

    Ok(())
}

HiDPI Screenshots

Capture high-resolution images using deviceScaleFactor (similar to Puppeteer's page.setViewport()).

use anyhow::Result;
use base64::Engine;
use cdp_html_shot::{Browser, CaptureOptions, ImageFormat, Viewport};

#[tokio::main]
async fn main() -> Result<()> {
    let browser = Browser::new().await?;
    let html = "<h1 style='font-size:48px'>Crystal Clear!</h1>";

    // Method 1: Quick HiDPI capture (2x resolution)
    let base64_image = browser.capture_html_hidpi(html, "h1", 2.0).await?;

    // Method 2: Full control with CaptureOptions
    let options = CaptureOptions::new()
        .with_format(ImageFormat::Png)
        .with_viewport(
            Viewport::new(1920, 1080)
                .with_device_scale_factor(3.0) // 3x for ultra-sharp images
        )
        .with_omit_background(true); // Transparent background

    let base64_image = browser
        .capture_html_with_options(html, "h1", options)
        .await?;

    // Decode and save
    let img_data = base64::prelude::BASE64_STANDARD.decode(base64_image)?;
    std::fs::write("hidpi_screenshot.png", img_data)?;

    Ok(())
}

Advanced Tab Control

Manually manage tabs, viewport, navigation, and element selection for complex scenarios.

use anyhow::Result;
use base64::Engine;
use cdp_html_shot::{Browser, CaptureOptions, Viewport};

#[tokio::main]
async fn main() -> Result<()> {
    let browser = Browser::new().await?;
    let tab = browser.new_tab().await?;

    // Set viewport with HiDPI scaling
    tab.set_viewport(
        &Viewport::new(1280, 720)
            .with_device_scale_factor(2.0)
            .with_mobile(false),
    )
    .await?;

    // Inject content
    tab.set_content("<h1>Complex Report</h1><div class='chart'>...</div>")
        .await?;

    // Wait for dynamic element and capture
    let element = tab.wait_for_selector(".chart", 5000).await?;
    let base64_image = element
        .screenshot_with_options(CaptureOptions::raw_png())
        .await?;

    // Execute JavaScript
    let title = tab.evaluate_as_string("document.title").await?;
    println!("Page title: {}", title);

    // Take full page screenshot
    let page_screenshot = tab
        .screenshot(CaptureOptions::high_quality_jpeg())
        .await?;

    // Cleanup
    tab.close().await?;
    browser.close_async().await?;

    Ok(())
}

Viewport Configuration

The Viewport struct provides full control over page dimensions and device emulation:

use cdp_html_shot::Viewport;

// Simple viewport
let viewport = Viewport::new(1920, 1080);

// HiDPI viewport (2x sharper images)
let viewport = Viewport::new(1920, 1080)
    .with_device_scale_factor(2.0);

// Mobile emulation
let viewport = Viewport::new(375, 812)
    .with_device_scale_factor(3.0)
    .with_mobile(true)
    .with_touch(true);

// Using the builder pattern
let viewport = Viewport::builder()
    .width(1440)
    .height(900)
    .device_scale_factor(2.0)
    .is_mobile(false)
    .build();

Capture Options

Fine-tune screenshot output with CaptureOptions:

use cdp_html_shot::{CaptureOptions, ImageFormat, Viewport};

// PNG with transparency
let opts = CaptureOptions::new()
    .with_format(ImageFormat::Png)
    .with_omit_background(true);

// High-quality JPEG
let opts = CaptureOptions::new()
    .with_format(ImageFormat::Jpeg)
    .with_quality(95);

// Convenience presets
let opts = CaptureOptions::raw_png();
let opts = CaptureOptions::high_quality_jpeg();
let opts = CaptureOptions::hidpi();       // 2x scale
let opts = CaptureOptions::ultra_hidpi(); // 3x scale

License

Licensed under either of Apache License, Version 2.0 or MIT license at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
Commit count: 30

cargo fmt