PHPology is a collective of highly skilled, award winning, web gurus.
Contact Raj on 07985 467 213 or email [email protected]

Merging transparent PNG images side by side with PHP and GD

I had to work on a small script for a front developer at work where he wanted to view a single image which basically merged 40 images side by side.

Below is the example image he was trying to achieve:

He complained that doing this manually via Photoshop was pain in the arse so if it was possible to do via PHP. There is no limitations on how many images you want to merge which was a benefit for him as the number of images he wanted to merge using this script varied.

As the images were PNG and were transparent we wanted to retain the transparency and the below code seems to do the trick.

Below is the code as the end result. 

ini_set('display_errors', 1);
ini_set('memory_limit', -1);

//where are the images stored
$src_dir = './';  

//because our images were named as number i.e. 0.png, 1.png, 2.png, 3.png etc etc, using the range()
$numbers = range(0, 37); //we have 38 images

$dest_w = 0; 

foreach ($numbers as $key => $val){ 
    $src = $src_dir . $val . '.png';  
    $size = getimagesize($src);  

    $src_gds[$key]['img'] = imagecreatefrompng($src); 
    $src_gds[$key]['w'] = $size[0];
    $src_gds[$key]['h'] = $size[1];

    $dest_w += $src_gds[$key]['w'];
    $hts[] = $src_gds[$key]['h'];

$dest_h = max($hts); 

$dest_gd = imagecreatetruecolor($dest_w, $dest_h);

imagealphablending($dest_gd, false);
$col = imagecolorallocatealpha($dest_gd, 0, 0, 0, 127);

imagefilledrectangle($dest_gd, 0, 0, $dest_w, $dest_w, $col);
imagealphablending($dest_gd, true);

$dest_x = 0; 

foreach ($src_gds as $gd)
    imagecopyresampled($dest_gd, $gd['img'], $dest_x, 0, 0, 0, $gd['w'], $gd['h'], $gd['w'], $gd['h']); 
    imagealphablending($gd['img'], true);

    $dest_x += $gd['w'];


//output the image to the browser rather then save to disk
header("Content-type: image/png"); 

imagealphablending($dest_gd, false);
imagesavealpha($dest_gd, true);