Hi,

I want to capture snapshot of a URL. User enters URL, hits Capture button and sees the captured image of that website.

I have done some google-ing but not real solution it.

Does anyone know any example in PHP and only on Linux? Not interested 3rd party websites though.

Thanks

Dani AI

Generated

Short primer: wanted a self-hosted PHP/Linux solution (no third-party services). and rightly pointed to online APIs, but if you must run everything on your server the typical pattern is: call a headless renderer from PHP (a small binary or a Node worker) and save the produced image. The choices below balance ease, JS compatibility, and server cost.

A simple, low-dependency option is wkhtmltoimage (part of wkhtmltopdf). It’s a single CLI binary that renders pages headless (Qt WebKit) and can output PNG/JPEG; perfect for quick snapshots and small scale. Call it from PHP with proper escaping and error checks:

$url = 'http://example.com';
$output = '/var/www/html/screenshots/example.png';
$cmd = '/usr/bin/wkhtmltoimage --quality 90 --width 1280 ' . escapeshellarg($url) . ' ' . escapeshellarg($output) . ' 2>&1';
exec($cmd, $out, $rv);
if ($rv !== 0) { error_log("wkhtmltoimage failed: " . implode("\n", $out)); }

Install and docs: see the wkhtmltopdf project. (wkhtmltopdf.org)

For modern, JS-heavy sites use Headless Chrome (CLI or Puppeteer). Chrome/Chromium supports a --screenshot flag and full JS execution; Puppeteer (Node) gives you a reusable browser instance, fine-grained waits, and element-level screenshots — much faster and more reliable under load than launching a browser per request. Example CLI and programmatic options are documented in Chrome and Puppeteer docs. (developer.chrome.com)

Operational and security notes: validate/allowlist URLs to prevent SSRF; run rendering under a low‑privilege account; cache results and use a queue or a persistent browser process for throughput. PhantomJS is no longer maintained — avoid it for new projects. For SSRF prevention and best practices see OWASP guidance. (owasp.org)

Recommendation: start with wkhtmltoimage for simple pages; move to Headless Chrome + Puppeteer if pages rely on complex JS. In all cases sanitize inputs, escape shell args, and add caching/worker queues before putting the feature behind a public form.

Recommended Answers

All 7 Replies

Just posted a link in this thread. Hope it helps.

Member Avatar for Member #120589

Nice link Pritaeas.

How about thumbalizr for online capture (no downloads!)? http://www.thumbalizr.com/

They even have an API.

commented: That's a better link ! +14

I'll try a bit more and harrrrder if I can find something. Thanks guys

Member Avatar for Member #120589

IT WORKS!!

Go to thumbalizr and sign up for a free API with downloadable PHP script to store captured images into your own directories. DON'T use the downloaded code - it doesn't work well. Instead, go to GitHUb and download mptr's version:

I had to make slight changes for it to work (in red)

index.php

<?php

define('_THUMBALIZR',1);
require('thumbalizrrequest.php');

// See README.textile for further reference.
$config = array(
	// Change the value to your api-key.
	'api_key' => 'xx', //PUT YOUR API KEY IN HERE instead of xx
);
$image = new thumbalizrRequest($config);
$image->request('http://www.daniweb.com/');

if($image->headers['Status'] == 'OK' || $image->headers['Status'] == 'LOCAL') {
	$image->output();
} else {
	print_r($image->headers);
}
?>

thumbalizrrequest.php

<?php
if(!defined('_THUMBALIZR'))
	die('no access');

class thumbalizrRequest {
	public $config;
	
	public function __construct($config) {
		if(!is_array($config))
			return false;
		
		$this->config = array(
			// Equivalent to $thumbalizr_config.
			'api_key' => (!isset($config['api_key'])) ? 'ece7a9d1724b318084b2abe37a5c2ed2' : $config['api_key'],
			'service_url' => (!isset($config['service_url'])) ? 'http://api.thumbalizr.com/' : $config['service_url'],
			'use_local_cache' => (!isset($config['use_local_cache'])) ? true : $config['use_local_cache'],
			'local_cache_dir' => (!isset($config['local_cache_dir'])) ? 'cache' : $config['local_cache_dir'],
			'local_cache_expire' => (!isset($config['local_cache_expire'])) ? 300 : $config['local_cache_expire'],
			// Equivalent to $thumbalizr_defaults.
			'width' => (!isset($config['width'])) ? 250 : $config['width'],
			'delay' => (!isset($config['delay'])) ? 8 : $config['delay'],
			'encoding' => (!isset($config['encoding'])) ? 'png' : $config['encoding'],
			'quality' => (!isset($config['quality'])) ? 90 : $config['quality'],
			'bwidth' => (!isset($config['bwidth'])) ? 1280 : $config['bwidth'],
			'bheight' => (!isset($config['bheight'])) ? 1024 : $config['bheight'],
			'mode' => (!isset($config['mode'])) ? 'screen' : $config['mode']
		);
	}

//THE CODE CARRIES ON, BUT NO CHANGES FROM THIS POINT ONWARDS
//JUST DOWNLOAD FROM GITHUB


?>

NICE!!

Member Avatar for Member #120589

IT WORKS!!

Go to thumbalizr and sign up for a free API with downloadable PHP script to store captured images into your own directories. DON'T use the downloaded code - it doesn't work well. Instead, go to GitHUb and download mptr's version:

I had to make slight changes for it to work (in red)

index.php

<?php

define('_THUMBALIZR',1);
require('thumbalizrrequest.php');

// See README.textile for further reference.
$config = array(
	// Change the value to your api-key.
	'api_key' => 'xx', //PUT YOUR API KEY IN HERE instead of xx
);
$image = new thumbalizrRequest($config);
$image->request('http://www.daniweb.com/');

if($image->headers['Status'] == 'OK' || $image->headers['Status'] == 'LOCAL') {
	$image->output();
} else {
	print_r($image->headers);
}
?>

thumbalizrrequest.php

<?php
if(!defined('_THUMBALIZR'))
	die('no access');

class thumbalizrRequest {
	public $config;
	
	public function __construct($config) {
		if(!is_array($config))
			return false;
		
		$this->config = array(
			// Equivalent to $thumbalizr_config.
			'api_key' => (!isset($config['api_key'])) ? 'xx' : $config['api_key'], //PUT api key here
			'service_url' => (!isset($config['service_url'])) ? 'http://api.thumbalizr.com/' : $config['service_url'],
			'use_local_cache' => (!isset($config['use_local_cache'])) ? true : $config['use_local_cache'],
			'local_cache_dir' => (!isset($config['local_cache_dir'])) ? 'cache' : $config['local_cache_dir'],
			'local_cache_expire' => (!isset($config['local_cache_expire'])) ? 300 : $config['local_cache_expire'],
			// Equivalent to $thumbalizr_defaults.
			'width' => (!isset($config['width'])) ? 250 : $config['width'],
			'delay' => (!isset($config['delay'])) ? 8 : $config['delay'],
			'encoding' => (!isset($config['encoding'])) ? 'png' : $config['encoding'],
			'quality' => (!isset($config['quality'])) ? 90 : $config['quality'],
			'bwidth' => (!isset($config['bwidth'])) ? 1280 : $config['bwidth'],
			'bheight' => (!isset($config['bheight'])) ? 1024 : $config['bheight'],
			'mode' => (!isset($config['mode'])) ? 'screen' : $config['mode']
		);
	}

//THE CODE CARRIES ON, BUT NO CHANGES FROM THIS POINT ONWARDS
//JUST DOWNLOAD FROM GITHUB


?>

//EDIT

Sorry, had to edit line 103 too:

if(isset($destroy))

My aim is not to be tied up with anyone else or 3rd party websites so I'll have to carry on searching. If they are dead I am dead too!

Thanks for the help anyway

Member Avatar for Member #120589

Fair one. It was fun researching it anyway.
My take is that you'll need some heavy duty non-php code to take a snapshot. I saw some java examples, again as 3rd party apps.

Good luck. If you do find a good method, please post back.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.