Project
PHP - Automatic sprite generation WITH CSS
Category
Published
Aug 15 2014 by FaTe
Share
Quick jump
Creating sprite sheets is frankly a pain in the !$$

Instead I've created this mere 100 or lines of code which displays a basic form to multi-select a group of images, additionally you can set the filename to output as and padding in PX to leave before next image in line. Finally you can set a quality % to output as with 50 as default, higher the quality the bigger the size of the output.

Click "Start process" and the script will copy each image one at a time from the temp directory, acquire its information and read the full image into string format stored with its data in an array. Once an image is processed its deleted.

The process repeats until we have the image data at which point it generates a canvas the required dimensions with images in the sprite being stacked too the right horizontally. At the same time the image is generated the CSS required to use the sprite sheet is also generated along with a test HTML file.

Example: If you selected images and decided to save as "my_project" then the following would be generated:

[*] my_project.css
[*] my_project.html
[*] my_project.jpg

The output is designed to use the images as backgrounds in DIV elements, however you can of course re-use it however you like and even alter the code for function use for example.

Copy the whole code below to your editor or notepad and save as "gensprites.php"

Enjoy
<?PHP /* Author: Graham Alexander - 2014 www.fatedev.com www.fatedev.nl www.fatebase.com --------------------------------------------------------------- Automatically generate image sprite sheet from images selected --------------------------------------------------------------- Script cycle: Select images > each img processed into array with attributes > php generates canvas with each img > kill canvas */ print '<html><head><title>Gensprites</title></head><body>'; if(!isset($_POST['process'])){ print '<form action="gensprites.php" method="POST" enctype="multipart/form-data"><input type="hidden" name="process" value="1">'; print 'Select image files: <input type="file" name="filez[]" multiple="multiple"><hr />'; print 'Padding: <input type="text" size="3" value="5" name="paddingz">px<hr />'; print 'Quality: <input type="text" size="3" value="50" name="quality">%<hr />'; print 'Save as: <input type="text" size="15" value="" name="filenamez"> NO EXTENTION or SPACES<hr />'; print '<input type="submit" value="Start process">'; print '</form>'; DIE("</body></html>"); } $name = ($_POST['filenamez']? $_POST['filenamez'] : "gensprites"); $setup=Array("images"=>Array(), "X"=>0, "current_x"=>0, "total_size"=>0, "canvas_width"=>0, "canvas_height"=>0, "padding"=>(is_numeric($_POST['paddingz']) ? $_POST['paddingz'] : 0), "saveAs"=> $name.".jpg", "saveAsCSS"=> $name.".css", "saveAsHTML"=> $name.".html", "css_output"=>"/*Images*/", "html_output"=>'<html><head><title></title><link rel="stylesheet" href="'.$name.'.css" type="text/css"></head><body>', "last_img"=>"", "quality"=>(is_numeric($_POST['quality']) ? $_POST['quality'] : 50)); for($i=0; $i<count($_FILES["filez"]["name"]); $i++){ if($_FILES["filez"]["size"][$i]>0){ list($ImgWidth,$ImgHeight) = getimagesize($_FILES["filez"]["tmp_name"][$i]); #get dimensions $type = trim(str_replace("image/", "", $_FILES["filez"]["type"][$i])); #get the extention $temp = "temp.".$type; $setup['total_size']+=$_FILES["filez"]["size"][$i]; $setup["X"]+= $ImgWidth; #add to the total canvas width $setup['canvas_height'] = ($ImgHeight > $setup['canvas_height']? $ImgHeight : $setup['canvas_height']); #if bigger update if(move_uploaded_file($_FILES["filez"]["tmp_name"][$i], $temp)){ #shift the image locally as temp.$type switch ($type){ case 'jpg': $img = imagecreatefromjpeg("{$temp}"); break; case 'jpeg': $img = imagecreatefromjpeg("{$temp}"); break; case 'png': $img = imagecreatefrompng("{$temp}"); break; case 'gif': $img = imagecreatefromgif("{$temp}"); break; default: $img = imagecreatefromjpeg("{$temp}"); break; } $c_name = str_replace(" ","_", $_FILES["filez"]["name"][$i]); #replace spaces as 1st act if( is_numeric(substr($c_name,0,1)) ){ $c_name= "alpha_".$c_name; } #illegal numeric 1st char $setup["images"][]= Array("filename"=>$c_name, "size"=>$_FILES["filez"]["size"][$i], "type"=> ($type=="jpeg"?"jpg": $type), "width"=>$ImgWidth, "height"=>$ImgHeight, "img"=>$img ); # set the actual img data to the array to use in the build @unlink($temp); #kill the temp } } } if(!count($setup["images"])){ DIE("No images processed!"); } #Time to generate a canvas. As CSS doesn't care if its wide, tall or square then its just simplier to go horizontal so we always reference Y as 0px only X changes $setup["canvas_width"] = ($setup["padding"] * (count($setup["images"])-1) ) + $setup["X"]; #add the padding spacing minus the last spot + the canvas total X from images themselfes $setup["last_img"]=$setup["images"][count($setup["images"])-1]["filename"]; $bg = imagecreatetruecolor($setup["canvas_width"], $setup['canvas_height']); #create the canvas imagefill($bg, 0, 0, imagecolorallocate($bg, 255, 255, 255)); # optional for full alpha imagealphablending($bg, TRUE); foreach($setup["images"] as $img){ imagecopyresampled($bg, $img["img"], $setup["current_x"], 0, 0, 0, $img["width"], $img["height"], $img["width"], $img["height"]); #insert this image $fname= str_replace(".".$img["type"], "", $img["filename"]); $setup["css_output"].= "rn"."#".$fname."{ display:inline-block; width:".$img["width"]."px; height:".$img["height"]."px; background:url('".$setup["saveAs"]."'); background-position: ".($setup['current_x']?"-":"").$setup['current_x']."px 0px; } /* ".$img["filename"]." */"; #Build the text file output with CSS $setup["html_output"].= "rn".$fname.' <div id="'.$fname.'"></div><hr />'; $setup["current_x"]+= $img['width'] + ($img["filename"]!=$setup["last_img"] && $setup["padding"]? $setup["padding"] : 0); #shift x place with padding if not last image } imagejpeg($bg, $setup["saveAs"], 50);// the 50 is to set the quality, 0 = worst-smaller file, 100 = better-bigger file ImageDestroy($bg); $setup["html_output"].="</body></html>"; file_put_contents($setup["saveAsCSS"] , $setup["css_output"]); file_put_contents($setup["saveAsHTML"], $setup["html_output"]); print nl2br($setup['css_output']); print "<hr />Process report - ".count($setup["images"])." images:<hr />". $setup["saveAs"]." - ".$setup["canvas_width"]."px * ".$setup['canvas_height']."px @ ".ceil(filesize($setup["saveAs"])/1024)."kb + ".$setup["saveAsCSS"]. "<hr />Total filesize of individual images: ".ceil($setup['total_size']/1024)."kb<hr />". "<a href='gensprites.php'>Make another sprite</a></body></html>"; ?>
Other projects you might like