O'Reilly logo

PHP Hacks by Jack D. Herrington

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

Hack #30. Split One Image into Multiple Images

Use PHP's graphics engine to break a single large image into multiple small images.

Sometimes it's handy to have a group of smaller images that make up a single image rather than the one small image. An example is "Create the Google Maps Scrolling Effect" [Hack #26] , which scrolls many smaller images around the screen seamlessly, creating the effect of moving around one large image. To accomplish that trick, though, you might have to break up a large image first; this hack does just that.

The Code

Save the code in Example 4-5 as imgsplit.php.

Example 4-5. Breaking up images

	<?php
	$width = 100;
	$height = 100;
	
	$source = @imagecreatefromjpeg( "source.jpg" );
	$source_width = imagesx( $source );
	$source_height = imagesy( $source );
	
	for( $col = 0; $col < $source_width / $width; $col++)
	{
		for( $row = 0; $row < $source_height / $height; $row++)
		{
			$fn = sprintf( "img%02d_%02d.jpg", $col, $row );
			
			echo( "$fn\n" );
			
			$im = @imagecreatetruecolor( $width, $height );
			imagecopyresized( $im, $source, 0, 0,
				$col * $width, $row * $height, $width, $height,
				$width, $height );
			imagejpeg( $im, $fn );
			imagedestroy( $im );
			}
		} 
		?>

This is the inverse of the code in Example 4-6 in the upcoming "Hacking the Hack" section of this hack. It creates—from a single big image—lots of smaller images and puts them in a grid. It's a useful match for the Google Maps scrolling effect hack in "Create the Google Maps Scrolling Effect" [Hack #26] .

The constants at the top of the file define how big the output images should be. The script reads in the source image and figures out how big it is; then it uses a set of nested for loops to iterate around all of the grid items, creating an image, copying the section from the original image, and then saving the image.

Running the Hack

This code is run on the command line using PHP's command-line interpreter:

	% php imgsplit.php
	img00_00.jpg
	img01_00.jpg
	…

The script looks for a file called source.jpg and breaks it up into a set of files named img<col>_<row>.jpg, where the col and row items are padded with zeroes. So the image in column zero, row zero would be named img00_00.jpg. Each created image is 100x100 pixels. Those values are set with the $width and $height values at the top of the script.

Hacking the Hack

Instead of splitting images, how about merging images? The next script creates a single large image from a collage of smaller images. You can use this code as the foundation of a scrolling panorama, as shown in "Create the Google Maps Scrolling Effect" [Hack #26] , or simply as a collage of multiple images suitable for a background or desktop image.

Save the code shown in Example 4-6 as imgmerge.php.

Example 4-6. Merging images, yet another task PHP can handle easily

	<?php
	$targetsize_x = 4000;
	$targetsize_y = 4000;
	$outfile = "merged.jpg";
	$quality = 100;

	$im = @imagecreatetruecolor( $targetsize_x, $targetsize_y );
	
	$sources = array();
	$dh = opendir( "." );
	while (($file = readdir($dh)) !== false)
	{
		if ( preg_match( "/[.]jpg$/", $file ) &&
			$file!= $outfile )
		{
			$sources []= imagecreatefromjpeg( $file );
		}
	}
	
	$x = 0;
	$y = 0;
	$index = 0;
	while( true )
	{
		$width =imagesx( $sources[ $index ] );
		$height = imagesy( $sources[ $index ] );
		
		imagecopy( $im, $sources[ $index ],
			$x, $y, 0, 0, $width, $height );
			
		$x += $width;
		if ( $x >= $targetsize_x )
		{
			$x = 0;
			$y += $height;
			if ( $y >= $targetsize_y )
				break;
		}

		$index += 1;
		if ( $index >= count( $sources ) )
			$index = 0;
	}

	imagejpeg( $im, $outfile, $quality );

	imagedestroy( $im );
	?>

This is a fairly simple script that takes image files from a directory and stores them into an array of sources. Then the script creates a huge image, into which it copies the original source images. The while loop wraps around the large image, creating rows of smaller images, until it gets to the bottom of the output image. At the end of the script, the large composite image is saved as a JPEG using imagejpeg().

This code is run from the command line in a directory full of JPEG images.

Tip

The input files must end with the .jpg extension, and all of the input images must be the same size. Otherwise, the composite will have lots of "empty" spaces in it (if it doesn't crash altogether).

An example image is shown in Figure 4-7.

The command is run in this way:

	% php imgmerge.php
One of the sample source images

Figure 4-7. One of the sample source images

The output file is created in the same directory as the source images, and it is named merged.jpg. With some sample images of my wife (Lori) and my daughter (Megan), I created the composite shown in Figure 4-8.

The completed graphic, shown scaled down in Firefox

Figure 4-8. The completed graphic, shown scaled down in Firefox

Even better—and nothing more than a happy accident—Firefox does something pretty cool here. It scales the image down to fit it within the browser. If you hold the mouse over the image, the cursor will turn into a magnifying glass, and you can zoom in on the composite to see it at 100% magnification.

You can adjust the quality of the merged image by tweaking the $quality value. This value goes from 0 to 100, with 100 being the best quality. $targetsize_x and $targetsize_y define the desired width and height of the merged image, and the $outfile variable specifies the filename of the merged image.

See Also

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required