Crop an image in PHP using CwCrop

This post is about how to crop an image with CwCrop and PHP on the server. There’s no spectacular php-code to be found (just basic stuff), but as a small example this should be sufficient.

CwCrop is a mootools plugin to select a rectangular area from an image, it delivers the x- and y-coordinates of the top left corner and the width and height of the selected area. The small example below consists of a single page, which either shows the original image and the crop tool – or the resulting, cropped image.

Please note: You need PHP 5 with the GD library on your server.

PHP crop function

The following class-function crops a given image ($src_file) to a target file ($target_file) by using imagecopy. Given are the top-left x and y coordinates and width plus height of the area.

class Imaging
{
	public static function cropImage($src_file, $target_file, $x, $y, $width, $height)
	{
		list($width_orig, $height_orig, $type) = getimagesize($src_file);

		if ($width_orig == 0 || $height_orig == 0) {
			return false;
		}
		
		if ($type == IMG_JPG) {
			$image = @imagecreatefromjpeg($src_file);
		}
		else if ($type == IMG_PNG || $type == 3) { // php bug seemingly..
			$image = @imagecreatefrompng($src_file);
		}
		else if ($type == IMG_GIF) {
			$image = @imagecreatefromgif($src_file);
		}
		else {
			return false;
		}
		if (!$image) {
			return false;
		}
		$x = abs(intval($x));
		$y = abs(intval($y));
		$width = abs(intval($width));
		$height = abs(intval($height));
		
		if ( $width == 0 || $height == 0 || (($x + $width) > $width_orig) || (($y + $height) > $height_orig) ) {
			return false;
		}
		
		$image_p = imagecreatetruecolor($width, $height);
		if ( !imagecopy($image_p, $image, 0, 0, $x, $y, $width, $height) ) {
			return false;
		}
		return imagejpeg($image_p, $target_file, 95);
	}
}

PHP inside the page

Here we set the directory and filenames. In this case the original image and the cropped result are in the same folder. Note: The directory must be writeable for the webserver and the path is relative to the webserver document-root.

If we receive the posted values from the form, we read them from the $_POST-array, set our target_file-variable (the result) and crop the source image to this target. If that somehow makes problems, we unset the target_file-variable again.

$path_images = '/images/'; // modify this
$src_name = 'original.jpg'; // modify this
$target_name = 'cropped-file.jpg'; // modify this
$script_self = $_SERVER['PHP_SELF']; // better: absolute URL here

$src_original = $path_images.$src_name;
list($width, $height, $type) = getimagesize($_SERVER['DOCUMENT_ROOT'].$src_original);

if (isset($_POST['crop'])) {

	$vars = array('x','y','w','h');
	foreach ($vars as $var) {
		$crop[$var] = isset($_POST['crop'][$var]) ? intval($_POST['crop'][$var]) : 0;
	}

	$target_file = $path_images.$target_name;
	$res = Imaging::cropImage($_SERVER['DOCUMENT_ROOT'].$src_original, $_SERVER['DOCUMENT_ROOT'].$target_file, $crop['x'], $crop['y'], $crop['w'], $crop['h']);
	if (!$res) {
		unset($target_file);
	}
}

HTML part of the page

This is a simple HTML 5-page, with stylesheet and javascripts. Note that we set the maximal size for cropping to the width and height of the original image, which we found via getimagesize(). Then we either display the resulting image with a random GET-parameter (to circumvent the browser cache) – or the original image along with the HTML for CwCrop and a form.

<!DOCTYPE html>
<html lang="en">
<head>
	<title>CwCrop example</title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	
	<link rel="stylesheet" type="text/css" href="css/ysr-crop.css" media="all">
	<script type="text/javascript" src="js/mootools-1.2.5-core-yc.js"></script>
	<script type="text/javascript" src="js/mootools-1.2.5.1-more.js"></script>
	<script type="text/javascript" src="js/ysr-crop.js"></script>

	<script type="text/javascript">
		var cwcrop_handler;
		window.addEvent("domready", function() {
			cwcrop_handler = new CwCrop({
				maxratio: {x: 1.5, y: 1.5},
				minsize: {x: 100, y: 100},
				maxsize: {x: <?=$width ?>, y: <?=$height ?>},
				onCrop: function(values) {
		    	    document.forms["crop"].elements["crop[x]"].value = values.x;
		        	document.forms["crop"].elements["crop[y]"].value = values.y;
			        document.forms["crop"].elements["crop[w]"].value = values.w;
			        document.forms["crop"].elements["crop[h]"].value = values.h;
		    		document.forms["crop"].submit();
			    }
			});
		});
	</script>
<body>
	<?php if (isset($target_file)) { ?>

		<h3>Cropped Image</h3>

		<p><img src="<?=$target_file ?>?randomstuff=<?=rand(0, 32768) ?>" alt="Cropped image"></p>
		<p><button onclick="document.location.href='<?=$script_self ?>'">Try again</button></p>

	<?php } else { ?>
	
		<h3>Crop here</h3>

		<div id="imgouter">
			<div id="cropframe" style="background-image: url('<?=$src_original ?>')">
					<div id="draghandle"></div>
					<div id="resizeHandleXY" class="resizeHandle"></div>
					<div id="cropinfo" rel="Click to crop">
						<div title="Click to crop" id="cropbtn"></div>
						<div id="cropdims"></div>
					</div>
				</div>
			
			<div id="imglayer" style="width: <?=$width ?>px; height: <?=$height ?>px; padding: 1px; background-position: center center; background-image: url('<?=$src_original ?>')">
			</div>
		</div>

		<form name="crop" method="post" action="<?=$script_self ?>">
			<p><button onclick="cwcrop_handler.doCrop()">Crop</button></p>

			<input type="hidden" name="crop[x]" value="0">
			<input type="hidden" name="crop[y]" value="0">
			<input type="hidden" name="crop[w]" value="0">
			<input type="hidden" name="crop[h]" value="0">
		</form>
		
	<?php } ?>
</body>
</html>

All together

You can download all required files here ». If you use this, be sure to change the path settings in the php-part (with “modify this”), your image folder (which must be writeable!) and the paths for your CSS and JavaScript-files.

5 Replies to “Crop an image in PHP using CwCrop”

  1. This script shows the script error like this Uncaught TypeError: Object [object Object] has no method ‘getSize’

  2. Many thanks !
    btw i’m trying to get a preview picture after clicked crop button. (the cropped picture is save under the same name each time).picture on the screen dont change whereas the picture has changed (we can see the preview under firebug of the new cropped image) Do you have an idea about this?

    i use a simple $().src to refresh url of the dom. but something is missing… i need to reload the page to see.

    1. Might be a problem with the browser cache if the image filename is the same. Try adding a random number after the filename (like I did in the php code) with javascript.

Leave a Reply

Your email address will not be published. Required fields are marked *