Slideshow: one big image for all

Most of website I’ve set up weight is given by the images of the slideshow.

Here’s a simple PHP function that can be usefull to reduce both weight and number of connection for this element.

The concept behind this function is pretty simple:

  1. take an array of images (jpg/png/gif)
  2. merge them in a unique big jpeg image
  3. return the url to this one.
  4. using css sprite tecnique, set this big image as the background of every <div> of the slideshow with a different background-position.

Here’s the code:


function merge_images($images, $config=null){
	if(empty($images)) return 'No images';
	$config = array_merge(
					'w'		=>	'700',
					'h'		=>	'370',
					'q'		=>	'50',
					'r'		=>	false

	$combined_image = imagecreatetruecolor($config['w']*count($images), $config['h']);

	$cache_name = '';
	foreach($images as $image){
		$cache_name .= $image['path'].';';
	$cache_name .= serialize($config);
	$cache_name = md5($cache_name);

	$cache_dir = get_template_directory().'/cache/';
	if (!@is_dir($cache_dir)){
		if (!@mkdir($cache_dir)){
			die('Couldn\'t create cache dir: '.$cache_dir);
	$cache_url = get_bloginfo('template_url').'/cache/'.$cache_name.'.jpg';
	$cache_path = $cache_dir.$cache_name.'.jpg';

	if(!file_exists($cache_path) || IMAGE_MERGE_FORCE_REFRESH===true){
		foreach($images as $array_index => $image){
			$src = $image['url'].'?'.http_build_query($config, '', '&');

			$info = getimagesize($src);
				case 'image/jpeg':
					$image = imagecreatefromjpeg($src);
				case 'image/png':
					$image = imagecreatefrompng($src);
				case 'image/gif':
					$image = imagecreatefromgif($src);
					die('unknow mime type');
					0, 0, 0,


	return $cache_url;

The second parameter $config is optional array of width, height, quality, and resample;
if not passed the default values are 800×600, 50% and ‘do not resample’

built to support all the parameter used by timthumb.

Using it is not a big deal:

  1. retrieve the image list from your CMS
  2. pass it to this function as first parameter
  3. print some div with in-line style setting the image url as background and position (wich is always number_of_the_image * width)

Here’s an example:

	$width = 1900;
	$height = 500;
	$config = array(
	define('IMAGE_MERGE_FORCE_REFRESH', false);
	$images = wp_get_imagelist_for_slideshow(
	$merged_image_uri = merge_images($images, $config);
	$tpl = '
			'\') no-repeat scroll -%opos%px -%vpos%px transparent;width:'.
			<div class="black_grad z_6"></div>
			<div class="caption_container z_10">
				<div class="container_16 z_10">
					<div class="grid_16 text_right color_fff font_30 font_palatino">%caption%</div>
	foreach ($images as $array_index => $image){
		//printf($tpl, $array_index * $width, 0);
		echo str_replace(
				$array_index * $width,
				($array_index == 0) ? '' : 'display:none'

Using this method will give us some benefits:

  • if someone uploads an image with wrong dimension, this will be re-sized and it will not brake the layout
  • you will never serve a too heavy image, because this function can force it to have fixed jpeg quality; for example 60%
  • for an averange of 5 images per slideshow we have only one concurrent http connection
  • the total weight of the page is significantly decreased: on ‘’ I was able to reduce from ~900K (~200k per image per 4 images) to an unique big image of ~400k

it cannot be applied to a dynamically sized slideshow: for example a full screen images or an adaptive design: image size have to be know.