use base64::engine::general_purpose::STANDARD;
use base64::Engine as _;
use headless_chrome::Tab;
pub const DEFAULT_MAX_DIMENSION: u32 = 1400;
const JPEG_QUALITY: u8 = 85;
pub fn capture_screenshot_data_url(tab: &Tab, max_dimension: u32) -> Result<String, String> {
let png = tab
.capture_screenshot(
headless_chrome::protocol::cdp::Page::CaptureScreenshotFormatOption::Png,
None,
None,
true,
)
.map_err(|e| format!("screenshot capture failed: {e}"))?;
let img =
image::load_from_memory(&png).map_err(|e| format!("screenshot decode failed: {e}"))?;
let (width, height) = (img.width(), img.height());
let longest = width.max(height);
let resized = if max_dimension > 0 && longest > max_dimension {
let scale = f64::from(max_dimension) / f64::from(longest);
#[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
let new_width = (f64::from(width) * scale).round().max(1.0) as u32;
#[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
let new_height = (f64::from(height) * scale).round().max(1.0) as u32;
img.resize(new_width, new_height, image::imageops::FilterType::Lanczos3)
} else {
img
};
let mut jpeg = Vec::new();
{
let mut encoder =
image::codecs::jpeg::JpegEncoder::new_with_quality(&mut jpeg, JPEG_QUALITY);
encoder
.encode_image(&resized)
.map_err(|e| format!("screenshot encode failed: {e}"))?;
}
Ok(format!("data:image/jpeg;base64,{}", STANDARD.encode(jpeg)))
}
#[cfg(test)]
mod tests {
use super::DEFAULT_MAX_DIMENSION;
#[test]
fn default_max_dimension_sane() {
const {
assert!(DEFAULT_MAX_DIMENSION >= 1280 && DEFAULT_MAX_DIMENSION <= 1600);
}
}
}