Archive for April, 2011

Image Manipulation With jQuery and PHP GD

Advertisement in Image Manipulation With jQuery and PHP GD
 in Image Manipulation With jQuery and PHP GD  in Image Manipulation With jQuery and PHP GD  in Image Manipulation With jQuery and PHP GD

One of the numerous advantages brought about by the explosion of jQuery and other JavaScript libraries is the ease with which you can create interactive tools for your site. When combined with server-side technologies such as PHP, this puts a serious amount of power at your finger tips.

In this article, I’ll be looking at how to combine JavaScript/jQuery with PHP and, particularly, PHP’s GD library to create an image manipulation tool to upload an image, then crop it and finally save the revised version to the server. Sure, there are plugins out there that you can use to do this; but this article aims to show you what’s behind the process. You can download the source files (updated) for reference.

We’ve all seen this sort of Web application before — Facebook, Flickr, t-shirt-printing sites. The advantages are obvious; by including a functionality like this, you alleviate the need to edit pictures manually from your visitors, which has obvious drawbacks. They may not have access to or have the necessary skills to use Photoshop, and in any case why would you want to make the experience of your visitors more difficult?

Before You Start

For this article, you would ideally have had at least some experience working with PHP. Not necessarily GD — I’ll run you through that part, and GD is very friendly anyway. You should also be at least intermediate level in JavaScript, though if you’re a fast learning beginner, you should be fine as well.

A quick word about the technologies you’ll need to work through this article. You’ll need a PHP test server running the GD library, either on your hosting or, if working locally, through something like XAMPP. GD has come bundled with PHP as standard for some time, but you can confirm this by running the phpinfo() function and verifying that it’s available on your server. Client-side-wise you’ll need a text editor, some pictures and a copy of jQuery.

Setting Up The Files

And off we go, then. Set up a working folder and create four files in it: index.php, js.js, image_manipulation.php and css.css. index.php is the actual webpage, js.js and css.css should be obvious, while image_manipulation.php will store the code that handles the uploaded image and then, later, saves the manipulated version.

In index.php, first let’s add a line of PHP to start a PHP session and call in our image_manipulation.php file:

After that, add in the DOCTYPE and skeleton-structure of the page (header, body areas etc) and call in jQuery and the CSS sheet via script and link tags respectively.

Add a directory to your folder, called imgs, which will receive the uploaded files. If you’re working on a remote server, ensure you set the permissions on the directory such that the script will be able to save image files in it.

First, let’s set up and apply some basic styling to the upload facility.

The Upload Functionality

Now to some basic HTML. Let’s add a heading and a simple form to our page that will allow the user to upload an image and assign that image a name:

<h1>Image uploader and manipulator</h1>

Please note that we specify enctype=’multipart/form-data’ which is necessary whenever your form contains file upload fields.

As you can see, the form is pretty basic. It contains 3 fields: an upload field for the image itself, a text field, so the user can give it a name and a submit button. The submit button has a name so it can act as an identifier for our PHP handler script which will know that the form was submitted.

Let’s add a smattering of CSS to our stylesheet:

/* -----------------
| UPLOAD FORM
----------------- */
#imgForm { border: solid 4px #ddd; background: #eee; padding: 10px; margin: 30px; width: 600px; overflow:hidden;}
	#imgForm label { float: left; width: 200px; font-weight: bold; color: #666; clear:both; padding-bottom:10px; }
	#imgForm input { float: left; }
	#imgForm input[type="submit"] {clear: both; }
	#img_upload { width: 400px; }
	#img_name { width: 200px; }

Now we have the basic page set up and styled. Next we need to nip into image_manipulation.php and prepare it to receive the submitted form. Which leads nicely on to validation…

Validating The Form

Open up image_manipulation.php. Since we made a point above of including it into our HTML page, we can rest assured that when it’s called into action, it will be present in the environment.

Let’s set up a condition, so the PHP knows what task it is being asked to do. Remember we named our submit button upload_form_submitted? PHP can now check its existence, since the script knows that it should start handling the form.

This is important because, as I said above, the PHP script has two jobs to do: to handle the uploaded form and to save the manipulated image later on. It therefore needs a technique such as this to know which role it should be doing at any given time.

/* -----------------
| UPLOAD FORM - validate form and handle submission
----------------- */

if (isset($_POST['upload_form_submitted'])) {
	//code to validate and handle upload form submission here
}

So if the form was submitted, the condition resolves to true and whatever code we put inside, it will execute. That code will be validation code. Knowing that the form was submitted, there are now five possible obstacles to successfully saving the file: 1) the upload field was left blank; 2) the file name field was left blank; 3) both these fields were filled in, but the file being uploaded isn’t a valid image file; 4) an image with the desired name already exists; 5) everything is fine, but for some reason, the server fails to save the image, perhaps due to file permission issues. Let’s look at the code behind picking up each of these scenarios, should any occur, then we’ll put it all together to build our validation script.

Combined into a single validation script, the whole code looks as follows.

/* -----------------
| UPLOAD FORM - validate form and handle submission
----------------- */

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

	//error scenario 1
	if (!isset($_FILES['img_upload']) || empty($_FILES['img_upload']['name'])) {
		$error = "Error: You didn't upload a file";

	//error scenario 2
	} else if (!isset($_POST['img_name']) || empty($_FILES['img_upload'])) {
		$error = "Error: You didn't specify a file name";
	} else {

		$allowedExtensions = array('jpg', 'jpeg', 'gif', 'png');
		preg_match('/\.('.implode($allowedExtensions, '|').')$/', $_FILES['img_upload']['name'], $fileExt);
		$newPath = 'imgs/'.$_POST['img_name'].'.'.$fileExt[0];

		//error scenario 3
		if (file_exists($newPath)) {
			$error = "Error: A file with that name already exists";

		//error scenario 4
		} else if (!in_array(substr($fileExt[0], 1), $allowedExtensions)) {
			$error = 'Error: Invalid file format - please upload a picture file';

		//error scenario 5
		} else if (!copy($_FILES['img_upload']['tmp_name'], $newPath)) {
			$error = 'Error: Could not save file to server';

		//...all OK!
		} else {
			$_SESSION['newPath'] = $newPath;
			$_SESSION['fileExt'] = $fileExt;
		}
	}
}

There are a couple of things to note here.

$error & $_SESSION['newPath']

Firstly, note that I’m using a variable, $error, to log whether we hit any of the hurdles. If no error occurs and the image is saved, we set a session variable, $_SESSION['new_path'], to store the path to the saved image. This will be helpful in the next step where we need to display the image and, therefore, need to know its SRC.

I’m using a session variable rather than a simple variable, so when the time comes for our PHP script to crop the image, we don’t have to pass it a variable informing the script which image to use — the script will already know the context, because it will remember this session variable. Whilst this article doesn’t concern itself deeply with security, this is a simple precaution. Doing this means that the user can affect only the image he uploaded, rather than, potentially, someone else’s previously-saved image — the user is locked into manipulating only the image referenced in $error and has no ability to enforce the PHP script to affect another image.

The $_FILES superglobal

Note that even though the form was sent via POST, we access the file upload not via the $_POST superglobal (i.e. variables in PHP which are available in all scopes throughout a script), but via the special $_FILES superglobal. PHP automatically assigns file fields to that, provided the form was sent with the required enctype='multipart/form-data' attribute. Unlike the $_POST and $_GET superglobals, the $_FILES superglobal goes a little “deeper” and is actually a multi-dimensional array. Through this, you can access not only the file itself but also a variety of meta data related to it. You’ll see how we can use this information shortly. We use this meta data in the third stage of validation above, namely checking that the file was a valid image file. Let’s look at this code in a little more detail.

Confirming the upload is an image

It’s sensible that we don’t allow the user to proceed if the uploaded file is not an image. So we need to look out for this. First, we create an array of allowed file extensions:

$allowedExtensions = array('jpg', 'jpeg', 'gif', 'png');

We then check whether or not the extension of the uploaded file is in that array. To do this, we of course need to extract the file extension. Surprisingly, the superglobal doesn’t provide this directly, so instead we’ll extract it with a regular expression.

Regular expressions are typically considered one of the hardest parts of programming to master. This is definitely true, yet they are often extremely valuable. If you want to read up more on regular expressions, take a look at Smashing Magazine’s articles Crucial Concepts Behind Advanced Regular Expressions or the excellent Regular-Expressions.info. The concept is essentiall matching patterns within strings. We know that our extension is the final part of the final name, preceded by a dot, so that forms the basis of our pattern:

preg_match('/\.('.implode($allowedExtensions, '|').')$/', $_FILES['img_upload']['name'], $fileExt);

preg_match() is the preferred function in PHP to match via REGEXP. It takes three arguments: the pattern, the string to look in, and an array to save matches to. So if a match is found — and of course it should be — our file extension will live in $fileExt[0], i.e. the first and only key of the array of matches.

Patterns are expressed as strings, and inside forward slashes (usually, but not always), so please ignore these parts. Our actual pattern starts with the dot. It has a backslash before it as it needs escaping, because otherwise it would be read as a special character (unescaped dots denote wildcard characters in the regular expression syntax). This is no different to having to escape quotes when using them inside strings, e.g.

"...and then he said \"hello, there\"";

The next part says: match any ONE of our allowed extensions. Since these live in our array, we convert them into a string via the implode() function, separated by the pipe character. Finally, the dollar character forces the expression to match the end of the string — required in our case, since a file extension is always at the end of a filename. So by the time the PHP engine has evaluated this pattern, it looks as though we had specified this (which is much more readable):

'/\.(jpg|jpeg|gif|png)$/'

Saving the file

All uploaded files are assigned a temporary home by the server until such time as the session expires or they are moved. So saving the file means moving the file from its temporary location to a permanent home. This is done via the copy() function, which needs to know two rather obvious things: what’s the path to the temporary file, and what’s the path to where we want to put it.

The answer to the first question is read from the tmp_name part of the $_FILES superglobal. The answer to the second is the full path, including new filename, to where you want it to live. So it is formed of the name of the directory we set up to store images (/imgs), plus the new file name (i.e. the value entered into the img_name field) and the extension. Let’s assign it to its own variable, $newPath and then save the file:

$newPath = 'imgs/'.$_POST['img_name'].'.'.$fileExt;
...
copy($_FILES['img_upload']['tmp_name'],$newPath);

Reporting Back and Moving On

What happens next depends entirely on whether an error occurred, and we can find it out by looking up whether $error is set. If it is, we need to communicate this error back to the user. If it’s not set, it’s time to move on and show the image and let the user manipulate it. Add the following above your form:

<?php if (isset($error)) echo '<p id="error">'.$error.'</p>'; ?>

If there’s an error, we’d want to show the form again. But the form is currently set to show regardless of the situation. This needs to change, so that it shows only if no image has been uploaded yet, i.e. if the form hasn’t been submitted yet, or if it has but there was an error. We can check whether an uploaded image has been saved by interrogating the $_SESSION['newPath'] variable. Wrap your form HTML in the following two lines of code:

<?php if (!isset($_SESSION['newPath']) || isset($_GET['true'])) { ?>

<?php } else echo '<img src="'.$_SESSION['newPath'].'" />'; ?>

Now the form appears only if an uploaded image isn’t registered — i.e. $_SESSION['newPath'] isn’t set — or if new=true is found in the URL. (This latter part provides us with a means of letting the user start over with a new image upload should they wish so; we’ll add a link for this in a moment). Otherwise, the uploaded image displays (we know where it lives because we saved its path in $_SESSION['newPath']).

This is a good time to take stock of where we are, so try it out. Upload an image, and verify that that it displays. Assuming it does, it’s time for our JavaScript to provide some interactivity for image manipulation.

Adding Interactivity

First, let’s extend the line we just added so that we a) give the image an ID to reference it later on; b) call the JavaScript itself (along with jQuery); and c) we provide a “start again” link, so the user can start over with a new upload (if necessary). Here is the code snippet:

<?php } else { ?>
	<img id="uploaded_image" src="" />
	<p>start over with new image

	<script src="http://www.google.com/jsapi"></script>
	<script>google.load("jquery", "1.5");</script>
	<script src="js.js"></script>

Note that I defined an ID for the image, not a class, because it’s a unique element, and not one of the many (this sounds obvious, but many people fail to observe this distinction when assigning IDs and classes). Note also, in the image’s SRC, I’m appending a random string. This is done to force the browser not to cache the image once we’ve cropped it (since the SRC doesn’t change).

Open js.js and let’s add the obligatory document ready handler (DRH), required any time you’re using freestanding jQuery (i.e. not inside a custom function) to reference or manipulate the DOM. Put the following JavaScript inside this DRH:

$(function() {
	// all our JS code will go here
});

We’re providing the functionality to a user to crop the image, and it of course means allowing him to drag a box area on the image, denoting the part he wishes to keep. Therefore, the first step is to listen for a mousedown event on the image, the first of three events involved in a drag action (mouse down, mouse move and then, when the box is drawn, mouse up).

var dragInProgress = false;

$("#uploaded_image").mousedown(function(evt) {
	dragInProgress = true;
});

And in similar fashion, let’s listen to the final mouseup event.

$(window).mouseup(function() {
	dragInProgress = false;
});

Note that our mouseup event runs on window, not the image itself, since it’s possible that the user could release the mouse button anywhere on the page, not necessarily on the image.

Note also that the mousedown event handler is prepped to receive the event object. This object holds data about the event, and jQuery always passes it to your event handler, whether or not it’s set up to receive it. That object will be crucial later on in ascertaining where the mouse was when the event fired. The mouseup event doesn’t need this, because all we care about if is that the drag action is over and it doesn’t really matter where the mouse is.

We’re tracking whether or not the mouse button is currently depressed in a variable, . Why? Because, in a drag action, the middle event of the three (see above) only applies if the first happened. That is, in a drag action, you move the mouse whilst the mouse is down. If it’s not, our mousemove event handler should exit. And here it is:

$("#uploaded_image").mousemove(function(evt) {
	if (!dragInProgress) return;
});

So now our three event handlers are set up. As you can see, the mousemove event handler exits if it discovers that the mouse button is not currently down, as we decided above it should be.

Now let’s extend these event handlers.

This is a good time to explain how our JavaScript will be simulating the drag action being done by the user. The trick is to create a DIV on mousedown, and position it at the mouse cursor. Then, as the mouse moves, i.e. the user is drawing his box, that element should resize consistently to mimic that.

Let’s add, position and style our DIV. Before we add it, though, let’s remove any previous such DIV, i.e. from a previous drag attempt. This ensures there’s only ever one drag box, not several. Also, we want to log the mouse coordinates at the time of mouse down, as we’ll need to reference these later when it comes to drawing and resizing ourDIV. Extend the mousedown event handler to become:

$("#uploaded_image").mousedown(function(evt) {
	dragInProgress = true;
	$("#drag_box").remove();
	$("<div>").appendTo("body").attr("id", "drag_box").css({left: evt.clientX, top: evt.clientY});
	mouseDown_left = evt.clientX;
	mouseDown_top = evt.clientY;
});

Notice that we don’t prefix the three variables there with the 'var' keyword. That would make them accessible only within the mousedown handler, but we need to reference them later in our mousemove handler. Ideally, we’d avoid global variables (using a namespace would be better) but for the purpose of keeping the code in this tutorial concise, they’ll do for now.

Notice that we obtain the coordinates of where the event took place — i.e. where the mouse was when the mouse button was depressed — by reading the clientX and clientY properties of the event object, and it’s those we use to position our DIV.

Let’s style the DIV by adding the following CSS to your stylesheet.

#drag_box { position: absolute; border: solid 1px #333; background: #fff; opacity: .5; filter: alpha(opacity=50); z-index: 10; }

Now, if you upload an image and then click it, the DIV will be inserted at your mouse position. You won’t see it yet, as it’s got width and height zero; only when we start dragging should it become visible, but if you use Firebug or Dragonfly to inspect it, you will see it in the DOM.

So far, so good. Our drag box functionality is almost complete. Now we just need to make it respond to the user’s mouse movement. What’s involved here is very much what we did in the mousedown event handler when we referenced the mouse coordinates.

The key to this part is working out what properties should be updated, and with what values. We’ll need to change the box’s left, top, width and height.

Sounds pretty obvious. However, it’s not as simple as it sounds. Imagine that the box was created at coordinates 40×40 and then the user drags the mouse to coordinates 30×30. By updating the box’s left and top properties to 30 and 30, the position of the top left corner of the box would be correct, but the position of its bottom right corner would not be where the mousedown event happened. The bottom corner would be 10 pixels north west of where it should be!

To get around this, we need to compare the mousedown coordinates with the current mouse coordinates. That’s why in our mousedown handler, we logged the mouse coordinates at the time of mouse down. The box’s new CSS values will be as follows:

  • left: the lower of the two clientX coordinates
  • width: the difference between the two clientX coordinates
  • top: the lower of the two clientY coordinates
  • height: the difference between the two clientY coordinates

So let’s extend the mousemove event handler to become:

$("#uploaded_image").mousemove(function(evt) {
	if (!dragInProgress) return;
	var newLeft = mouseDown_left < evt.clientX ? mouseDown_left : evt.clientX;
	var newWidth = Math.abs(mouseDown_left - evt.clientX);
	var newTop = mouseDown_top < evt.clientY ? mouseDown_top : evt.clientY;
	var newHeight = Math.abs(mouseDown_top - evt.clientY);
	$('#drag_box').css({left: newLeft, top: newTop, width: newWidth, height: newHeight});
});

Notice also that, to establish the new width and height, we didn't have to do any comparison. Although we don't know, for example, which is lower out of the mousedown left and the current mouse left, we can subtract either from the other and counter any negative result by forcing the resultant number to be positive via Math.abs(), i.e.

result = 50 – 20; //30
result = Math.abs(20 – 50); //30 (-30 made positive)

One final, small but important thing. When Firefox and Internet Explorer detect drag attempts on images they assume the user is trying to drag out the image onto their desktop, or into Photoshop, or wherever. This has the potential to interfere with our creation. The solution is to stop the event from doing its default action. The easiest way is to return false. What's interesting, though, is that Firefox interprets drag attempts as beginning on mouse down, whilst IE interprets them as beginning on mouse move. So we need to append the following, simple line to the ends of both of these functions:

return false;

Try your application out now. You should have full drag box functionality.

Saving the Cropped Image

And so to the last part, saving the modified image. The plan here is simple: we need to grab the coordinates and dimensions of the drag box, and pass them to our PHP script which will use them to crop the image and save a new version.

Grabbing the drag box data

It makes sense to grab the drag box's coordinates and dimensions in our mouseup handler, since it denotes the end of the drag action. We could do that with the following:

var db = $("#drag_box");
var db_data = {left: db.offset().left, top: db.offset().top, width: db.width(), height: db.height()};

There's a problem, though, and it has to do with the drag box's coordinates. The coordinates we grab above are relative to the body, not the uploaded image. So to correct this, we need to subtract the position, relative to the body, of the image itself, from them. So let's add this instead:

var db = $("#drag_box");
if (db.width() == 0 || db.height() == 0 || db.length == 0) return;
var img_pos = $('#uploaded_image').offset();
var db_data = {
	left: db.offset().left – img_pos.left,
	top: db.offset().top - img_pos.top,
	width: db.width(),
	height: db.height()
};

What's happening there? We're first referencing the drag box in a local shortcut variable, db, and then store the four pieces of data we need to know about it, its left, top, width and height, in an object db_data. The object isn't essential: we could use separate variables, but this approach groups the data together under one roof and might be considered tidier.

Note the condition on the second line, which guards against simple, dragless clicks to the image being interpreted as crop attempts. In these cases, we return, i.e. do nothing.

Note also that we get the left and top coordinates via jQuery's offset() method. This returns the dimensions of an object relative to the document, rather than relative to any parent or ancestor with relative positioning, which is what position() or css('top/right/bottom/left') would return. However, since we appended our drag box directly to the body, all of these three techniques would work the same in our case. Equally, we get the width and height via the width() and height() methods, rather than via css('width/height'), as the former omits 'px' from the returned values. Since our PHP script will be using these coordinates in a mathematical fashion, this is the more suitable option.

For more information on the distinction between all these methods, see my previous article on SmashingMag, Commonly Confused Bits of jQuery.

Let's now throw out a confirm dialogue box to check that the user wishes to proceed in cropping the image using the drag box they've drawn. If so, time to pass the data to our PHP script. Add a bit more to your mouseup handler:

if (confirm("Crop the image using this drag box?")) {
	location.href = "index.php?crop_attempt=true&crop_l="+db_data.left+"&crop_t="+
db_data.top+"&crop_w="+db_data.width+"&crop_h="+db_data.height;
} else {
	db.remove();
}

So if the user clicks 'OK' on the dialogue box that pops up, we redirect to the same page we're on, but passing on the four pieces of data we need to give to our PHP script. We also pass it a flag crop_attempt, which our PHP script can detect, so it knows what action we'd like it to do. If the user clicks 'Cancel', we remove the drag box (since it's clearly unsuitable). Onto the PHP...

PHP: saving the modified file

Remember we said that our image_manipulation.php had two tasks — one to first save the uploaded image and another to save the cropped version of the image? It's time to extend the script to handle the latter request. Append the following to image_manipulation.php:

/* -----------------
| CROP saved image
----------------- */

if (isset($_GET["crop_attempt"])) {
	//cropping code here
}

So just like before, we condition-off the code area and make sure a flag is present before executing the code. As for the code itself, we need to go back into the land of GD. We need to create two image handles. Into one, we import the uploaded image; the second one will be where we paste the cropped portion of the uploaded image into, so we can essentially think of these two as source and destination. We copy from the source onto the destination canvas via the GD function imagecopy(). This needs to know 8 pieces of information:

  • destination, the destination image handle
  • source, the source image handle
  • destination X, the left position to paste TO on the destination image handle
  • destination Y, the top position “ “ “ “
  • source X, the left position to grab FROM on the source image handle
  • source Y, the top position “ “ “ “
  • source W, the width (counting from source X) of the portion to be copied over from the source image handle
  • source H, the height (counting from source Y) “ “ “ “

Fortunately, we already have the data necessary to pass to the final 6 arguments in the form of the JavaScript data we collected and passed back to the page in our mouseup event handler a few moments ago.

Let's create our first handle. As I said, we'll import the uploaded image into it. That means we need to know its file extension, and that's why we saved it as a session variable earlier.

switch($_SESSION["fileExt"][1]) {
	case "jpg": case "jpeg":
		var source_img = imagecreatefromjpeg($_SESSION["newPath"]);
		break;
	case "gif":
		var source_img = imagecreatefromgif($_SESSION["newPath"]);
		break;
	case "png":
		var source_img = imagecreatefrompng($_SESSION["newPath"]);
		break;
}

As you can see, the file type of the image determines which function we use to open it into an image handle. Now let's extend this switch statement to create the second image handle, the destination canvas. Just as the function for opening an existing image depends on image type, so too does the function used to create a blank image. Hence, let's extend our switch statement:

switch($_SESSION["fileExt"][1]) {
	case "jpg": case "jpeg":
		$source_img = imagecreatefromjpeg($_SESSION["newPath"]);
		$dest_ing = imagecreatetruecolor($_GET["crop_w"], $_GET["crop_h"]);
		break;
	case "gif":
		$source_img = imagecreatefromgif($_SESSION["newPath"]);
		$dest_ing = imagecreate($_GET["crop_w"], $_GET["crop_h"]);
		break;
	case "png":
		$source_img = imagecreatefrompng($_SESSION["newPath"]);
		$dest_ing = imagecreate($_GET["crop_w"], $_GET["crop_h"]);
		break;
}

You'll notice that the difference between opening a blank image and opening one from an existing or uploaded file is that, for the former, you must specify the dimensions. In our case, that's the width and height of the drag box, which we passed into the page via the $_GET['crop_w'] and $_GET['crop_h'] vars respectively.

So now we have our two canvases, it's time to do the copying. The following is one function call, but since it takes 8 arguments, I'm breaking it onto several lines to make it readable. Add it after your switch statement:

imagecopy(
	$dest_img,
	$source_img,
	0,
	0,
	$_GET["crop_l"],
	$_GET["crop_t"],
	$_GET["crop_w"],
	$_GET["crop_h"]
);

The final part is to save the cropped image. For this tutorial, we'll overwrite the original file, but you might like to extend this application, so the user has the option of saving the cropped image as a separate file, rather than losing the original.

Saving the image is easy. We just call a particular function based on (yes, you guessed it) the image's type. We pass in two arguments: the image handle we're saving, and the file name we want to save it as. So let's do that:

switch($_SESSION["fileExt"][1]) {
	case "jpg": case "jpeg":
		imagejpeg($dest_img, $_SESSION["newPath"]); break;
	case "gif":
		imagegif($dest_img, $_SESSION["newPath"]); break;
	case "png":
		imagepng($dest_img, $_SESSION["newPath"]); break;
}

It's always good to clean up after ourselves - in PHP terms that means freeing up memory, so let's destroy our image handlers now that we don't need them anymore.

imagedestroy($dest_img);
imagedestroy($source_img);

Lastly, we want to redirect to the index page. You might wonder why we'd do this, since we're on it already (and have been the whole time). The trick is that by redirecting, we can lose the arguments we passed in the URL. We don't want these hanging around because, if the user refreshes the page, he'll invoke the PHP crop script again (since it will detect the arguments). The arguments have done their job, so now they have to go, so we redirect to the index page without these arguments. Add the following line to force the redirect:

header("Location: index.php"); //bye bye arguments

Final Touches

So that's it. We now have a fully-working facility to first upload then crop an image, and save it to the server. Don't forget you can download the source files (updated) for your reference.

There's plenty of ways you could extend this simple application. Explore GD (and perhaps other image libraries for PHP); you can do wonders with images, resizing them, distorting them, changing them to greyscale and much more. Another thing to think about would be security; this tutorial does not aim to cover that here, but if you were working in a user control panel environment, you'd want to make sure the facility was secure and that the user could not edit other user's files.

With this in mind, you might make the saved file's path more complex, e.g. if the user named it pic.jpg, you might actually name it on the server 34iweshfjdshkj4r_pic.jpg. You could then hide this image path, e.g. by specifying the SRC attribute as 'getPic.php' instead of referencing the image directly inside an image's SRC attribute. That PHP script would then open and display the saved file (by reading its path in the session variable), and the user would never be aware of its path.

The possibilities are endless, but hopefully this tutorial has given you a starting point.

(vf)


© Mitya for Smashing Magazine, 2011. | Permalink | Post a comment | Smashing Shop | Smashing Network | About Us
Post tags: ,


Useful Photoshop Video Tutorials

Advertisement in Useful Photoshop Video Tutorials
 in Useful Photoshop Video Tutorials  in Useful Photoshop Video Tutorials  in Useful Photoshop Video Tutorials

Photoshop is an amazing tool in the hands of Designers. There are numerous tutorials which shows you all tips and tricks to conquer Photoshop. Reading tutorials can be little irksome at times when you don’t want to spend hours and hours on long written steps. Why not try these Video tutorials which give you amazing amusement while learning. Check out these 30 tutorials which will leave you raving about it. So learn while you play (these videos).


Your First Rendezvous With Photoshop
This Photoshop tutorial is for beginners and the tips and tricks mentioned here will give you insight about Photoshop.

Photoshop-video-tutorial-37 in Useful Photoshop Video Tutorials

Photoshopping a Heroes Style Eclipse
In this tutorial you will create a Solar eclipse in Retro style.

Photoshop-video-tutorial-2 in Useful Photoshop Video Tutorials

Photoshopping Neon Text
Check out this tutorial to know how you can apply neon effect through Photoshop.

Photoshop-video-tutorial-1 in Useful Photoshop Video Tutorials

Old Photo Repair
Photo Restoration is a useful feature we can do in Photoshop and keep our memories safe.

Photoshop-video-tutorial-36 in Useful Photoshop Video Tutorials

Photoshoping a Print Ad From Start to Finish
This one is an advanced level tutorial which gives you insight of how to make a Print Ad in Photoshop.

Photoshop-video-tutorial-7 in Useful Photoshop Video Tutorials

Galactic Scene – Photoshop CS5 Tutorial
Watch this tutorial to learn how to create a Galactic Scene in Photoshop. This is an advance level tutorial.

Photoshop-video-tutorial-6 in Useful Photoshop Video Tutorials

Retro Text Effect
create a retro text effect through this tutorial.

Photoshop-video-tutorial-9 in Useful Photoshop Video Tutorials

How to Crop an Image
This is a quick tutorial wherein you will learn how to crop an image from different angles.

Photoshop-video-tutorial-8 in Useful Photoshop Video Tutorials

Vampire – Angelina Jolie
Watch out this video tutorial to know how to convert beautiful Angelina Jolie in to a blood sucking vampire.

Photoshop-video-tutorial-35 in Useful Photoshop Video Tutorials

Facebook Banners
Watch this tutorial to learn how you can make Facebook Banner through Photoshop.

Photoshop-video-tutorial-10 in Useful Photoshop Video Tutorials

What is a Clipping Mask Then?
This Photoshop tutorial is for beginners and author will explain you about Clipping Mask.

Photoshop-video-tutorial-38 in Useful Photoshop Video Tutorials

Photoshopping Digital Bokeh
Check out how to get magnificant results in Photoshop by creating Digital Bokeh.

Photoshop-video-tutorial-3 in Useful Photoshop Video Tutorials

Changing Eye Color – Adobe Photoshop CS5
Check out this tutorial for explaining how to change someone s eye color.

Photoshop-video-tutorial-12 in Useful Photoshop Video Tutorials

Radial Blur Using Photoshop
This tutorial deals with creating a Radial Blur in Photoshop.

Photoshop-video-tutorial-34 in Useful Photoshop Video Tutorials

Photoshopping Scrapbooks
We know Scrapbooks are not scrap but a place to memorize your memorize. Check out how to create onein Photoshop.

Photoshop-video-tutorial-4 in Useful Photoshop Video Tutorials

Creative Effects–Making an image sepia toned
learn how to create a vintage-style photograph, use infrared and solarization, apply creative layer blending, etc.

Photoshop-video-tutorial-13 in Useful Photoshop Video Tutorials

Photoshop CS5 Tutorial – Removing acne, pimples, and blemishes
Removing acne, pimples, and blemishes is so easy with Photoshop CS5. Check out this video to know more.

Photoshop-video-tutorial-15 in Useful Photoshop Video Tutorials

Correcting Exposure, Dynamic & Color in Photoshop
Check out this tutoral on changing exposure & color in Photoshop.

Photoshop-video-tutorial-33 in Useful Photoshop Video Tutorials

Tutorial Photoshop CS5 – Rain effect
Check out how to create a Rain effect in a landscape.

Photoshop-video-tutorial-16 in Useful Photoshop Video Tutorials

How to Combine 2 Images Seamlessly in Photoshop
Learn how transform two Images Seamlessly.

Photoshop-video-tutorial-20 in Useful Photoshop Video Tutorials

Photoshop CS5: Puppet Warp
Want to warp or manipulate your objects easily with the new Puppet Warp. Check out this Photoshop CS5 Video Tutorial.

Photoshop-video-tutorial-21 in Useful Photoshop Video Tutorials

Photoshop Quick Tips: Light Leaks in Photography
In this video you wll learn the process to create vintage style light leaks in Photoshop.

Photoshop-video-tutorial-31 in Useful Photoshop Video Tutorials

How to Photoshop Tilt Shift
If you are aware of Tilt Shift Photography, then you will like to check this video on How to Photoshop Tilt Shift.

Photoshop-video-tutorial-22 in Useful Photoshop Video Tutorials

Photoshop and The Alt Key
Check this video to know how important is using the Alt key in Photoshop. It saves your time and effort.

Photoshop-video-tutorial-23 in Useful Photoshop Video Tutorials

Advanced Brush Techniques
Check out some Photoshop Advanced Brush Techniques in this tutorial.

Photoshop-video-tutorial-24 in Useful Photoshop Video Tutorials

Creating a Realistic Drop-Shadow using Photoshop
Check out this tutorial for creating a realistic drop-shadow using Photoshop

Photoshop-video-tutorial-25 in Useful Photoshop Video Tutorials

Photoshop CS5 – Abstract Floral Manipulation
Learn how to create a abstract floral manipulation through this tutorial.

Photoshop-video-tutorial-17 in Useful Photoshop Video Tutorials

How to Photoshop a Person Into a Picture [In-Depth]
Every now and then we use editing techniques in Photoshop. Check out this videofor step-by-step directions to edit a person into a photo.

Photoshop-video-tutorial-19 in Useful Photoshop Video Tutorials

How to Use the Healing Brush and Patch Tool
Learn how you can use the healing brush and patch tool in photoshop.

Photoshop-video-tutorial-18 in Useful Photoshop Video Tutorials

Create and Then Shatter a Grid, while Making a Typographic Poster
Create a dark and grungy Typographic Poster using Photoshop and Illustrator.

Photoshop-video-tutorial-39 in Useful Photoshop Video Tutorials

Photo Enhancement in LAB
Check out how to work in the Lab color mode to enhance your photos in contrast and color balance using simple curves adjustments.

Photoshop-video-tutorial-26 in Useful Photoshop Video Tutorials

Photoshop ‘Triage’ with Rich Harrington
In this Photoshop ‘Triage’ video go through this work flow takes an image and makes it ‘pop’.

Photoshop-video-tutorial-27 in Useful Photoshop Video Tutorials

How to Add a Background Texture to a Portrait
Check out how to get a grunge look by adding a background texture to a portrait.

Photoshop-video-tutorial-28 in Useful Photoshop Video Tutorials

Design a Shiny Bass Guitar Illustration Using Photoshop
Check out how you can make a Guitar Illustration in Photoshop.

Photoshop-video-tutorial-40 in Useful Photoshop Video Tutorials

Zombie makeover
Learn howyou can create a good looking Man in to a Zombie.

Photoshop-video-tutorial-11 in Useful Photoshop Video Tutorials

Add Dramatic Color to Photographs
Learn how you can give amazing effects to simple looking images.

Photoshop-video-tutorial-30 in Useful Photoshop Video Tutorials


A Crash Course in Typography: Paragraphs and Special Characters

Advertisement in A Crash Course in Typography: Paragraphs and Special Characters
 in A Crash Course in Typography: Paragraphs and Special Characters  in A Crash Course in Typography: Paragraphs and Special Characters  in A Crash Course in Typography: Paragraphs and Special Characters

Body copy makes up the majority of many websites. Headlines and other bits of typography are often considered more fun to design, or more artistic, but without a good design for your body copy, your overall project will suffer.

Body copy design requires you to consider two separate parts: character styles, and paragraph styles. Proper use of special characters can greatly increase the level of professionalism in your designs. And good paragraph styling can make a huge difference in readability, and therefore the amount of time someone is willing to spend reading your copy.

Using Special Characters

There are a number of special characters you can use in your typography designs that add a level of polish and sophistication that is lacking from many designs. Incorporating these characters takes some extra time on the part of the designer, but the end result is almost always worth it.

Ligatures

Ligatures are sometimes considered antiquated, and don’t show up often in web type. They’re not seen much more often in print design, either. But if your goal is to create a typographic design that has an antique, traditional, or very formal look, adding ligatures can be a fantastic way to reinforce that design style. Ligatures can also improve readability among certain characters, in certain fonts (especially italics and obliques).

If you want to use ligatures in your designs, there’s a great CSS declaration you can use to implement it in Safari, Webkit-based browsers, and Chrome: text-rendering: optimizeLegibility;. Firefox is already using this rendering setting for font sizes over 20px. There are a few glitches with using this declaration, which are detailed in the Aesthetically Loyal article about Cross-Browser Kerning-Pairs and Ligatures.

Ligatures are most commonly used for the following character pairs (shown regular and italic):

2-ligatures in A Crash Course in Typography: Paragraphs and Special Characters

Hyphens and Dashes

Hyphens and dashes are two of the most improperly used characters in typography. Hyphens should only be used when hyphenating words. There are two different kinds of dashes: the en-dash and the em-dash. An en-dash is shorter, roughly the width of the letter “n” in a particular font (hence, the name). An em-dash is wider, roughly the width of the letter “m”.

2-dashes in A Crash Course in Typography: Paragraphs and Special Characters

En-dashes should be used when showing a range (such as January–March) or when creating an open compound word (South Carolina–Georgia border). To create an en-dash, just use –. The em-dash is used mostly in informal writing, and can replace commas, semicolons, colons, and parentheses. They’re often used instead of commas to set apart independent clauses or an abrupt change of thought. To create an em-dash, use —.

Smart Quotes

2-smartquotes in A Crash Course in Typography: Paragraphs and Special Characters

Smart quotes (sometimes also called “curly quotes”) are quotation marks that turn in toward the text they surround. There are both double and single smart quotes, and each requires a different html code. Smart quotes are often created automatically in word processing programs, but can be a huge pain for web typography.

Some CMSs, like WordPress, automatically convert quotes to smart quotes. While this is good in most cases, it can also cause problems, especially if you post code snippets on your blog (as you don’t want code snippets to contain curly quotes). In general text, though, you’ll want to use smart quotes for a more polished look in your body text.

Ampersands

Ampersands (‘&’) are another special character that are sometimes used in typographic designs. To create an ampersand, just use &. They work well in headlines and similar short blocks of text, but aren’t really appropriate for body text (despite the fact that many people seem to use them that way).

2-ampersand in A Crash Course in Typography: Paragraphs and Special Characters

Ampersands are appropriate for use artistically, or in instances where space is limited (like in a table). Don’t use an ampersand just as an abbreviation for the word “and”. If using an ampersand artistically, you may find that ampersands in italic fonts are more attractive than their regular counterparts. Italic ampersands tend to follow the older style, and closely resemble the letters “e” and “t”, which make up the Latin word “et” (which translates to “and”).

Other Special Characters

2-specialchar in A Crash Course in Typography: Paragraphs and Special Characters

Other special typographic characters include things like trademark (â„¢), registered (‘®’), and copyright (‘©’) symbols, tildes (‘Ëœ’), and pilcrows (‘¶’), among others.

If you use any of the above characters, make sure you use the proper entity codes for a professional and polished final result. About.com has an extensive table of entity codes for various typographical symbols and punctuation marks that makes a great quick-reference guide.

An additional note about pilcrows: using these rather than actual paragraph breaks can be an interesting technique for article intros that consist of multiple short paragraphs. Just make sure that you don’t use them throughout a long document, as they convert the entire document into one long text block, which is harder to read, especially onscreen.

Character and Word Spacing

The space between characters and words can be broken down into a few different areas. The basics are kerning, tracking, and word spacing. Kerning, which is the space around specific characters, is generally done automatically within individual font files. Programs like Photoshop or InDesign give you some control over kerning between individual characters, but on the web it’s mostly impractical.

Tracking is similar to kerning, but isn’t character-specific. The tracking can be adjusted easily with CSS, using letter-spacing. For the most part, adjusting the tracking of your text shouldn’t be overdone. But it can be used to great effect in small blocks of text. It’s most often seen in headlines or menus. Overdoing it can result in text that is difficult to read.

One place you’ll always want to use letter spacing is between strings of capital letters (includings small caps) and strings of numbers. Set a letter spacing of around .1em between capital letters, small caps, or numbers to improve legibility.

Word spacing can greatly improve readability if done correctly, as it makes word recognition easier. People often read words just by recognizing their shapes, and increasing the space slightly around each word can speed up this process. Word spacing is accomplished in CSS with word-spacing. Word spacing, by default, is .25 ems. It should be specified in ems, so that it adjusts according to text size. Also, word-spacing adjustments are made in relation to the default spacing. So if you specify a word spacing of 0.25 em, you’re actually getting a space of .5 em between words.

2-charspacing in A Crash Course in Typography: Paragraphs and Special Characters

Paragraph Formatting

The paragraph is often referred to as the most basic unit of language that has meaning. Paragraphs are the building blocks of text content, and yet all too often, designers do little more than specify the font face and size. There’s a host of other formatting options we should be considering when we format our paragraphs.

There are a few things to take into consideration beyond the choice of typeface. The goal of typography at the paragraph level is to create text that is highly readable. To that end, we need to consider the alignment of our text, as well as the line spacing and line width.

Alignment

2-alignment in A Crash Course in Typography: Paragraphs and Special Characters

There are four basic alignment types: left, right, center, and justified. As a general rule, centered type is harder to read. It’s fine for headlines or things like photo captions. But for paragraphs, it’s not suitable. This is due to the fact that ragged edges on the left-hand side of a paragraph reduce legibility (because readers have to search for the beginning of each line).

Right-aligned text presents the same problem as centered text for paragraphs. As a general rule, stick to either left-aligned or justified alignment for long blocks of text.

Line Height and Leading

In the days of hand-set print type, leading referred to the space between lines. The term comes from the literal strips of lead that were used to put extra space between lines of letters. Line height is similar to leading, except it refers to the overall height of lines, including the letters and space above and below them.

In CSS, you can adjust the line height to whatever you want. Line heights that are anywhere from 1.2x to 1.8x as tall as the text itself are generally the most readable. For example, if your text is 12px high, then your optimal line height would be between roughtly 14px and 22px. Play around with line heights until you find something that looks good for your particular project.

2-lineheight in A Crash Course in Typography: Paragraphs and Special Characters

You can see here how much easier text is to read at a taller line height.

Line Width

There are a few different theories regarding the perfect line length. Of course, the specifics between each vary. There are three basic ideas, though:

  • Line widths of roughly twelve words.
  • Line widths of roughly 39 characters (alphabet-and-a-half rule).
  • The points-times-two rule (which requires some math to convert it to work for the web).

The last one is really the only one that requires any explanation. If you multiply the size of your point times two, and then use that in picas rather than points, you’ll get your line width. In print design, this is easy enough to figure out. If, for example, your text height is 11 points, you’d have a line length of 22 picas (or just over 3.5″).

It takes an extra step to convert that to web use. Take that pica measurement you just got (multiply your text’s pixel size rather than points), and multiple it by 12 (because there are 12 points in a pica), and that will give you your line width in pixels.

For some examples of fantastic paragraph styles, check out Jon Tan’s 12 Examples of Paragraph Typography.

Great Paragraph Typography in Practice

Vogue Magazine

Vogue in A Crash Course in Typography: Paragraphs and Special Characters
The typography used in the paragraphs on the Vogue Magazine site has an obvious focus on readability. Generous line heights and a 14px font make reading even long blocks of text a breeze onscreen. In addition to the type size and spacing, using a very dark gray also makes the type more readable.

The basic code for this paragraph style is:

p {color: #333333; font-size: 14px; line-height: 24px; text-align: justify; font-family: Georgia,"Times New Roman",Times,serif;}

Sleepover, San Francisco

Sleepoversf in A Crash Course in Typography: Paragraphs and Special Characters

Sleepover applies a number of excellent attributes to their paragraph styling. First of all, headings are the same size as the body copy, but capitalized, with proper letter spacing:

{letter-spacing: 2px; text-transform: uppercase;}

The paragraphs themselves are also well-formatted. Font size is kept to 1 em, with a 1.85em line height (slightly larger than “normal”). The gray letter color is very easy on the eyes, though it might be too light for the taste of some. The added line height is extra important in cases like this, where there are other stylistic choices that might decrease readability. Here’s the basic paragraph code:

p {font-size: 1em; line-height: 1.85; color: #666666; text-align: justify; font-family: "Century Schoolbook",Century,Georgia,serif;}

Salt of the Earth

Saltpgh in A Crash Course in Typography: Paragraphs and Special Characters

Salt of the Earth uses a larger font than is commonly seen for body copy. They also use very generous line heights. Rather than lowering the contrast of the type by lightening the font, they’ve opted to use a darker background and a black font. It still results in easier-to-read text than black on white would be. Ample spacing between paragraphs is also used, which adds to scanability and breaks up long blocks of text.

The basic styles for this paragraph are:

p {font-family: Georgia,"Times New Roman",Times,serif; font-size: 16px; line-height: 30px; margin-bottom: 30px;}<

The Design Cubicle

Thedesigncubicle1 in A Crash Course in Typography: Paragraphs and Special Characters

The Design Cubicle uses what looks like a smaller font than any of the other examples here, and yet maintains similar readability. The other main difference here is that they use a sans-serif typeface (and an @font-face font, rather than a web-safe font), which is arguably more readable onscreen (the reverse is usually considered true with print typography). Contrast is good, with a medium gray background and a dark gray font.

Here’s the basic code for this paragraph style:

p {margin-bottom: 1.5em; font-size: 14px; line-height: 21px; font-family: "ff-dagny-web-pro-1","ff-dagny-web-pro-2",Verdana,sans-serif; font-weight: 400; color: #232D32;}

In Part 3…

We’ll talk about how to combine different typefaces, based on sound typographic design principles like weight and contrast, building on what we’ve covered here and in part 1.

Additional Resources


Multivariate Testing 101: A Scientific Method Of Optimizing Design

Advertisement in Multivariate Testing 101: A Scientific Method Of Optimizing Design
 in Multivariate Testing 101: A Scientific Method Of Optimizing Design  in Multivariate Testing 101: A Scientific Method Of Optimizing Design  in Multivariate Testing 101: A Scientific Method Of Optimizing Design

In a previous article on Smashing Magazine, I described A/B testing and various resources related to it. I have also covered the basics of multivariate testing in the past, yet in this post I’ll go deeper in the technical details of multivariate testing which is similar to A/B testing but with crucial differences.

In a multivariate test, a Web page is treated as a combination of elements (including headlines, images, buttons and text) that affect the conversion rate. Essentially, you decompose a Web page into distinct units and create variations of those units. For example, if your page is composed of a headline, an image and accompanying text, then you would create variations for each of them. To illustrate the example, let’s assume you make the following variations:

  • Headline: headline 1 and headline 2
  • Text: text 1 and text 2
  • Image: image 1 and image 2

The scenario above has three variables (headline, text and image), each with two versions. In a multivariate test, your objective is to see which combination of these versions achieves the highest conversion rate. By combinations, I mean one of the eight (2 × 2 × 2) versions of the Web page that we’ll come up with when we combine variations of the sections:

  • Headline 1 + Text 1 + Image 1
  • Headline 1 + Text 1 + Image 2
  • Headline 1 + Text 2 + Image 1
  • Headline 1 + Text 2 + Image 2
  • Headline 2 + Text 1 + Image 1
  • Headline 2 + Text 1 + Image 2
  • Headline 2 + Text 2 + Image 1
  • Headline 2 + Text 2 + Image 2

In multivariate testing, you split traffic between these eight different versions of the page and see which combination produces the highest conversion rate — just like in A/B testing, where you split traffic between two versions of a page.

Getting Started With Multivariate Testing

To create your first multivariate test, first choose a tool or framework that supports multivariate testing. You can use one of the tools listed in the section “Tools” in the end of this article. Please note that not all A/B testing tools support multivariate testing, so make sure your tool of choice allows it.

Once you’ve decided which tool to use, choose which sections to include in the test. As you know, a Web page can contain tens or hundreds of different sections (footer, headline, sidebar, log-in form, navigation buttons, etc.). You cannot include all of these sections in the test; creating variations for all of them would be an enormous task (and, as you’ll read below, the traffic requirements for the test will grow exponentially with each new section). Narrow it down to the few sections of the page that you think are most important to the conversion goal.

The following parts of a page (listed in order of importance) are typically included in a multivariate test:

  • Headline and heading,
  • Call-to-action buttons (color, text, size, placement),
  • Text copy (content, length, size),
  • Image (type, placement, size),
  • Form length.

The Difference Between A/B Testing And Multivariate Testing

Conceptually, the two techniques are similar, but there are crucial differences. First and foremost, the traffic requirements are different. As I said, the number of combinations that need to be tested grows exponentially in a multivariate test. You can test three or four versions in an A/B test and tens or hundreds of versions in a multivariate test. Clearly, then, a lot of traffic — and time — is required to arrive at meaningful results.

For example, if you have three sections with three variations each, the number of combinations is 27. Add another section with three variations, and the total number of combinations jumps to 81. If you want meaningful results, you can’t keep adding sections to the test. Be selective. A good rule is to limit the total number of combinations to 25 or fewer.

Variation-testing in Multivariate Testing 101: A Scientific Method Of Optimizing Design
Use A/B testing for large scale changes, not to refine or optimize existing designs. Image by Meet the Chumbeques

Another difference is in how these techniques are used. A/B testing is usually reserved for large radical changes (such as completely changing a landing page or displaying two different offers). Multivariate testing is used to refine and optimize an existing design. For the mathematically inclined, A/B testing is used to optimize for a global optimum, while multivariate testing is used to optimize for a local optimum.

One advantage of multivariate testing over A/B split testing is that it can tell you which part of the page is most influential on conversion goals. Say you’re testing the headline, text and image on your landing page. How do you know which part has the most impact? Most multivariate testing tools will give you a metric, called the “impact factor,� in their reports that tells you which sections influence the conversion rate and which don’t. You don’t get this information from A/B testing because all sections are lumped into one variation.

Types Of Multivariate Tests

Based on how you distribute traffic to your combinations, there are several types of multivariate tests (MVT):

Full factorial testing
This is the kind people generally refer to when they talk about multivariate testing. By this method, one distributes website traffic equally among all combinations. If there are 16 combinations, each one will receive one-sixteenth of all the website traffic. Because each combination gets the same amount of traffic, this method provides all of the data needed to determine which particular combination and section performed best. You might discover that a certain image had no effect on the conversion rate, while the headline was most influential. Because the full factorial method makes no assumptions with regard to statistics or the mathematics of testing, I recommend it for multivariate testing.

Results-by-ItoWorld in Multivariate Testing 101: A Scientific Method Of Optimizing Design
Record and compare the resulting traffic for each tested version. Image by ItoWorld

Partial or fractional factorial testing
As the name suggests, in this method only a fraction of all combinations are exposed to website traffic. The conversion rate for unexposed combinations is inferred from the ones that were included in the test. For example, if there are 16 combinations, then traffic is split among only eight of those. For the remaining eight, we get no conversion data, and hence we need to resort to fancy mathematics (with a few assumptions) for insight. For obvious reasons, I don’t recommend this method: even though there are fewer traffic requirements for partial factorial testing, the method forces too many assumptions. No matter how advanced the mathematics are, hard data is always better than inference.

Taguchi testing
This is the most esoteric method of all. A quick Google search reveals a lot of tools claiming to cut your testing time and traffic requirements drastically with Taguchi testing. Some might disagree, but I believe the Taguchi method is bit of a sham; it’s a set of heuristics, not a theoretically sound method. It was originally used in the manufacturing industry, where specific assumptions were made in order to decrease the number of combinations needing to be tested for QA and other experiments. These assumptions are not applicable to online testing, so you shouldn’t need to do any Taguchi testing. Stick to the other methods.

Do’s And Don’ts

I have observed hundreds of multivariate tests, and I have seen many people make the same mistakes. Here is some practical advice, direct from my experience.

Don’ts

  • Don’t include a lot of sections in the test.
    Every section you add effectively doubles the number of combinations to test. For example, if you’re testing a headline and image, then there are a total of four combinations (2 × 2). If you add a button to the test, there are suddenly eight combinations to test (2 × 2 × 2). The more combinations, the more traffic you’ll need to get significant results.

Do’s

  • Do preview all combinations.
    In multivariate testing, variations of a section (image, headline, button, etc.) are combined to create page variations. One of the combinations might be odd-looking or, worse, illogical or incompatible. For example, one combination might put together a headline that says “$15 off� and a button that says “Free subscription.� Those two messages are incompatible. Detect and remove incompatibilities at the preview stage.
  • Do decide which sections are most worthy of inclusion in the test.
    In a multivariate test, not all sections will have an equal impact on the conversion rate. For example, if you include a headline, a call-to-action button and a footer, you might come to realize that footer variations have little impact, and that headline and call-to-action variations produce winning combinations. You get a powerful section-specific report. Below is a sample report from Visual Website Optimizer. Notice how the button has more impact (91%) than the headline (65%):

    Mvt-small in Multivariate Testing 101: A Scientific Method Of Optimizing Design

  • Do estimate the traffic needed for significant results.
    Before testing, get a clear idea of how much traffic you’ll need in order to get statistically significant results. I’ve seen people add tens of sections to a page that gets just 100 visitors per day. Significant results from such a test would take months to accumulate. I suggest using a calculator, such as this A/B split and multivariate testing duration calculator, to estimate how much traffic your test will require. If it’s more than what’s acceptable, reduce some sections.

Case Studies

A lot of A/B testing case studies are on the Web, but unfortunately, finding multivariate test case studies is still difficult. So, I scoured the Internet and compiled relevant ones.

Software Download Case Study: downloads increased by 60%
This is one multivariate test I did to compare different versions of headlines and links. In the end, one of the variations resulted in a more than 60% increase in downloads.

Mvt-case-3 in Multivariate Testing 101: A Scientific Method Of Optimizing Design

Microsoft Multivariate Testing Case Study
This presentation details the variations that were tested for this website and the ultimate winner.

SiteSpect Case Studies
This page presents a dozen of multivariate testing case studies of large companies using multivariate testing and behavioral targeting to optimize their sites.

Maxymiser Case Studies
Another set of multivariate testing case studies.

Look Inside a 1,024-Recipe Multivariate Experiment
YouTube did a gigantic multivariate test in 2009. It can afford to do tests with a thousand-plus combinations because it has sufficient traffic.

Multivariate testing of an email newsletter
An agency tested color and text on the call-to-action button of its email newsletter. The best button had the highest CTR: 60%.

Multivariate Testing Tools And Resources

Tools

Google Website Optimizer
A free basic multivariate testing tool by Google. It’s great if you want to test the waters before investing money in multivariate testing. The downside? You’ll need to tag different sections of the Web page with JavaScript, which can be cumbersome. It’s also prone to error and forces you to rely on others (like the technology department) for implementation.

Visual Website Optimizer (Disclaimer: I am the developer of this tool)
The main advantage of this paid tool is that you can create a multivariate test visually in a WYSIWYG editor by choosing different sections of the page. You can then run the test without having to tag sections individually (although a snippet of code is required in the header). The tool includes heat map and click map reports.

WhichMVT
A website that publishes user reviews of all of the multivariate testing tools available on the market. If you are planning to adopt a multivariate testing tool for your organization, do your research on this website.

Enterprise testing tools
Omniture’s Test&Target, Autonomy’s Optimost, Vertster, Webtrends’ Optimize, and SiteSpect.

Resources

Expert Guide to Multivariate Testing Success, by Jonathan Mendez
A series of blog posts detailing different aspects of multivariate testing.

Fail Faster With Multivariate Testing (PDF)
An excellent free mini-guide to multivariate testing.

Online Testing Vendor Landscape
A commercial report by Forrester that compares the various testing vendors out there.

Lessons Learned from 21 Case Studies in Conversion Rate Optimization
This article discusses ideas for conversion rate optimization detailed through different case studies.

Related posts

You may be interested in the following related articles:

(al)


© Paras Chopra for Smashing Magazine, 2011. | Permalink | Post a comment | Smashing Shop | Smashing Network | About Us
Post tags: ,


Art Inspiration for the Weekend

Advertisement in Art Inspiration for the Weekend
 in Art Inspiration for the Weekend  in Art Inspiration for the Weekend  in Art Inspiration for the Weekend

Not long ago, we put together a post that was intended to assist our readers with that ever pressing issue of finding that inspirational recharge that is necessary for anyone in any creative field. In the design field, we tend to take our inspiration pretty seriously, and as a result we search both high and low to find any sparks we can root out. This can make finding some pieces that have not already been soaked up by the masses a bit difficult when trying to gather enough inspirational kindling to start a bonfire’s worth creative energy flowing freely. Which is precisely what we are hoping to do.

And we believe that we may have succeeded with this new showcase that we have amassed for you today. Pouring through the web’s latest and greatest artistic offerings, we have gathered some freshly picked creative fruits to help fuel your design pursuits. Take a browse through some of these breathtaking artists portfolio pieces, dissect and digest them, and we are sure that your wellsprings of inspiration will once more be overflowing.

Anna Anjos

Anna Anjos’ portfolio is packed to the brim of unique and playful characters that are so full of color and vibrant imagery that they are sure to kick start this inspirational journey. Her voice stands out across mediums, easily identifying her singularly whimsical work.

AAimage1 in Art Inspiration for the Weekend

AAimage2 in Art Inspiration for the Weekend

AAimage3 in Art Inspiration for the Weekend

AAimage4 in Art Inspiration for the Weekend

Dave Allsop

Dave Allsop’s gallery of work takes us deep into a darker corner of the fantasy art world. Having work that spans across numerous staples of the fantasy gaming genre, Dave was an easy artist to share in this showcase.

DAflesh Eating Poison in Art Inspiration for the Weekend

DAiceshear Mantle in Art Inspiration for the Weekend

DAphantom Cranes in Art Inspiration for the Weekend

DAShunned in Art Inspiration for the Weekend

Pat Perry

Pat Perry’s gallery of work was a must have for this showcase, and with a quick glance through just the handful we have gathered for you here, you will know why. Pat’s richly detailed artwork exists between the surreal and the fully abstract, bringing the work to life from an obviously imaginative mind.

PPimage1 in Art Inspiration for the Weekend

PPimage2 in Art Inspiration for the Weekend

PPimage3 in Art Inspiration for the Weekend

PPimage4 in Art Inspiration for the Weekend

Anthony Geoffroy

Switching gears in the showcase, we turn to Anthony Geoffroy’s portfolio over at Behance for a little dose of whimsy. Anthony’s caricatures are some of the most stunning examples of the artform that we have seen of late so we had to drop under the proverbial spotlight.

AGLostJack in Art Inspiration for the Weekend

AGDannyElfman in Art Inspiration for the Weekend

AGLostSawyer in Art Inspiration for the Weekend

AGEvilDead in Art Inspiration for the Weekend

Michal Dziekan

Taking the whimsy in a much darker direction, we land in the slightly twisted portfolio of imaginative illustrator Michal Dziekan. Michal’s work, which dances between the tongue in cheek and the macabre delivers commentary in a very artistic and biting manner.

MDragingmob in Art Inspiration for the Weekend

MDhanselngretel in Art Inspiration for the Weekend

MDbonappetit in Art Inspiration for the Weekend

MDhatepropaganda in Art Inspiration for the Weekend

Scott Altmann

Lingering in the those richly artistic in between places, we come to the gallery of work belonging to artist Scott Altmann. Scott’s work dances between the dark and the lightly surreal in his personal works, but is more direct and playful in his commissioned work. His work does run an interesting spectrum.

SAbirdseyeview in Art Inspiration for the Weekend

SAnightshadecover in Art Inspiration for the Weekend

SAelephant in Art Inspiration for the Weekend

SAfantasyrealms in Art Inspiration for the Weekend

Thomas Ehretsmann

That brings us to the fantastic acrylic work that fills Thomas Ehretsmann’s gallery. Combining his pulp style illustrations, with his rich acrylics, Thomas’ paintings feel like a page ripped from the old hard boiled detective novels.

TEimage1 in Art Inspiration for the Weekend

TEimage2 in Art Inspiration for the Weekend

TEimage3 in Art Inspiration for the Weekend

TEimage4 in Art Inspiration for the Weekend

Iain MacArthur

Refocusing our spotlight, we now find the portfolio of another very talented illustrator sharing in the limelight, Iain MacArthur. Iain’s extremely intricate drawings use a lot of random geometric shapes to create and give form to his gallery of work.

IMimage1 in Art Inspiration for the Weekend

IMimage2 in Art Inspiration for the Weekend

IMimage3 in Art Inspiration for the Weekend

IMimage4 in Art Inspiration for the Weekend

NIARK1

Jumping into another mixed media portfolio we move the showcase on to highlight the original artwork of french painter NIARK1. Using a combination of acrylics, pens, spraycans, and twisted imagery on wood panels, NIARK1’s style earned a richly deserved slot in the showcase.

N1ouvrebiderevenge in Art Inspiration for the Weekend

N1innercitypressure in Art Inspiration for the Weekend

N1mickeyskull in Art Inspiration for the Weekend

N1jenaiqunregret in Art Inspiration for the Weekend

Jonathan Bartlett

Jonathan Bartlett’s portfolio combines a light surrealism with a subtle, soft style that is somewhat reminiscent of Norman Rockwell’s work. Feeling as if the work was steeped in Americana, Jonathan’s art is sure to help get the inspired wheels a turning once more.

JBimage1 in Art Inspiration for the Weekend

JBimage2 in Art Inspiration for the Weekend

JBimage3 in Art Inspiration for the Weekend

JBimage4 in Art Inspiration for the Weekend

Mathis Rekowski

The gallery of work that we found of Mathis Rekowski, was breathtakingly chaotic and came with a charge of inspiration that we were sure would resonate with many of our readers. Dark in tone, but so colorful and playful at the same time, Mathis’ work is so creatively twisted that it is sure to satisfy.

MRimage1 in Art Inspiration for the Weekend

MRimage2 in Art Inspiration for the Weekend

MRimage3 in Art Inspiration for the Weekend

MRimage4 in Art Inspiration for the Weekend

Mike Friedrich

Mike Friedrich’s portfolio contains some very inspiring illustration works that range from the more playful and concrete in nature, to the somewhat darker edges of the abstract. The work alone was what got him featured on the showcase, but the interesting range didn’t hurt either.

MFimage1 in Art Inspiration for the Weekend

MFimage2 in Art Inspiration for the Weekend

MFimage3 in Art Inspiration for the Weekend

MFimage4 in Art Inspiration for the Weekend

FENIKS GRAFIX aka IKS

FENIKS GRAFIX’ body of work is one that is most would consider to be relatively whimsical, yet it still maintains a bit of an edge. This is not the easiest of balances to strike, but through IKS’ gallery we find how adeptly it can in fact be done.

IKSimage1 in Art Inspiration for the Weekend

IKSimage2 in Art Inspiration for the Weekend

IKSimage3 in Art Inspiration for the Weekend

IKSimage4 in Art Inspiration for the Weekend

Anton Semenov

Anton Semenov’s gallery overflows with darkly unique photomanipulations and other digital works that pass back and forth between frightening and haunting in their imagery. Almost as if Anton’s work delves into the world of nightmares and brings back some of its most mesmerizing and terrorizing captures with it.

ASimage1 in Art Inspiration for the Weekend

ASimage2 in Art Inspiration for the Weekend

ASimage3 in Art Inspiration for the Weekend

ASimage4 in Art Inspiration for the Weekend

Attila Brushvox

Coming back from the darkness, we have a much lighter and colorful portfolio to peak at with the often abstract artwork of Attila Brushvox. His work explores some very deep concepts even with their often playful, if not also a bit guarded, nature.

ABimage1 in Art Inspiration for the Weekend

ABimage2 in Art Inspiration for the Weekend

ABimage3 in Art Inspiration for the Weekend

ABimage4 in Art Inspiration for the Weekend

Artist Communities

In the last installment, we included a section that was dedicated to the numerous art communities that exist online, as wonderful outlets and resources for artists and enthusiasts alike. This time around, we thought that we would drop a couple of more into the showcase that were not featured the last time. So take a look at these new online communities for artists to see if perhaps they have what you are looking for. Be it a place to share your own work and connect with others, or be it a place to source out inspiring works or art!

Socurio

Socurio is an online location for artists looking to sell their work, and for those also looking to purchase it. This communal hub is one of the places that our readers turned us onto after the first post came out.

Socurio in Art Inspiration for the Weekend

Shadowness

Shadowness is an awesome collective for artists and designers wishing to connect and share their works. The site has an array of interesting features to take the experience to the proverbial next level. This was another user recommendation from the last post.

Shadowness in Art Inspiration for the Weekend

Dropr

Dropr is a new online artist community that we only recently discovered ourselves. This community is still in development, so there are many more exciting things to come, but it already seems promising in its early stages. So we expect to see some pretty interesting things develop.

Dropr1 in Art Inspiration for the Weekend

Online Apps for Artists

Now one of the main hindrances that many of us find, once we get that initial spark of inspiration is not having an available outlet to let the creativity flow. Which is where this section can come into play. Given that most of us spend a lot of time on the web, we have collected a handful of fun and handy online apps for image creation and editing for a quick and easy lightweight solution to this problem.

Sketchpad

Sketchpad is a relatively bare bones online paint/drawing application, or at least it feels that way from the simple, intuitive user interface. In all actuality, this app is fairly packed with options and functionality to appeal to and satisfy all levels of user.

Sketchpad in Art Inspiration for the Weekend

Aviary

Aviary is an online service that you are probably already familiar with, but we had to mention in this section of the roundup. Otherwise this portion of the post would have felt somewhat lacking. Aviary’s free suite of powerful online creation tools have proven popular to users from across the globe, if you haven’t already, you should check them out.

Aviary in Art Inspiration for the Weekend

Muro

Muro from Deviant Art is an online drawing/painting app that works with your Wacom tablet and allows you to upload your new creations directly into your DeviantArt account with the click of a button. There is also an export function for those who do not have an account, so no need to let that keep you from this waiting online canvas.

Muro in Art Inspiration for the Weekend

Pixlr

If you are looking for the depth of Photoshop in an online image editing app, then the closest that you are probably going to come is pixlr. pixlr is an incredibly loaded online image editor packed with functionality that is gaining in popularity among the online design community.

Pixlr in Art Inspiration for the Weekend

odosketch

Odosketch is an extremely simple and straightforward online sketch pad with a communal aspect driving the sharing function. From the whimsical to the classic, Odosketch provides a wonderful way to explore any inspired sparks kicking off in your mind.

Odosketch in Art Inspiration for the Weekend

Color Scheme Designer

Color Scheme Designer is our final tool, and another must feature app that this list would not have been complete without. With ranges of control options for the user, a complimentary, customized color scheme is waiting for your design with just a few clicks of the mouse.

Colorschemedesigner in Art Inspiration for the Weekend

Consider Some of Our Previous Posts


  •   
  • Copyright © 1996-2010 BlogmyQuery - BMQ. All rights reserved.
    iDream theme by Templates Next | Powered by WordPress