Crop and Resize Images with GD or ImageMagick (v1.1)

Published 8 years 4 months ago on December 17, 2007 — 9 min read

Over the past couple weeks, conversation has picked up quite a bit surrounding the Crop & Resize with JavaScript, PHP, and ImageMagick demo I put together nearly a year ago. There were quite a few requests made in the comments, and there were even some developers beginning to offer their very own code. I’ve always meant to revisit the example and beef up the feature set a bit, and I’ve finally been able to do just that.

Crop and Resize with GD

Above all, the most asked question was “why only ImageMagick“? I really don’t have a solid answer for that, other than the project itself was a way for me to get into using ImageMagick in a bit more detail than I ever had. I’m very happy to say that this version (as well as any future versions) now has equivalent ImageMagick and GD installations. You can choose one or the other in both the demo and download sections.

Demo: GD Crop and Resize v1.1

Demo: ImageMagick Crop and Resize v1.1

The demos and downloads have been removed temporarily due to a security issue. Replacements will be linked as soon as possible. Thank you for your patience. Please discontinue use as soon as possible until a revision has been posted.

Converting to GD wasn’t a major undertaking thanks to the helpful comments on version 1.0. It did take some time getting the slider to properly convey dimensions that would result in an accurate recreation of the image. One thing I have noticed is that the GD version seems to result in lower quality output when compared directly to ImageMagick. If you’ve got a server with both GD and ImageMagick installed, take a minute to use the same image in both demos to see what the differences are. I plan on looking into this much further, but if you’re a bit more knowledgeable on the subject, I’d love to hear what you have to say. Could the answer be that ImageMagick is simply a superior piece of software? I noticed that GD gives you the option to control the quality of images when using certain functions, so I left image output at 90% for the time being (the default is 75%).

If you have any positive or negative experiences with the new GD version, please feel free to post your findings either below, or in an email to me. I’d be greatly appreciative of any data that comes through.

Updates to the server side

There were a number of fixes that needed to be done to the server side of things straight away. First and foremost was Linux dependency. I must admit, a Windows server didn’t cross my mind when I was working on version 1.0, so I tried to polish things up a bit in that regard. The mv lines have been replaced, as well as an update or two elsewhere. There could very well be some more Windows-specific issues to be dealt with, unfortunately I don’t have any Windows servers at my disposal to test with. Feedback in this area will be particularly helpful.

A small series of updates I made was to the file upload process itself. The example now only accepts files with a MIME type of image/jpeg. Future versions will allow for more image formats, but I’d like to do some more research before including it. There are also some checks on the filenames themselves, as there were some issues with particular circumstances in version 1.0.

There was some logic repair regarding the $maxWidth and $maxHeight variables you can set in the first step. As per request, $minWidth and $minHeight have also been added. This should allow you to really narrow down what image dimensions will result using these variables in conjunction with the Cropper UI. One issue that has not been included yet is taking the minimum and maximum values set in the first step into account when users have reached the resize stage of version 1.1. This will be handled in a future release.

Finally, the last noticeable feature to be added server side was the inclusion of image rotation. When the final image is presented, image rotations of 90, 180, and 270 degrees will be available as well. You’re able to pull apart the code to retrieve which image you’d like to use, and can also include auto-generation using a form whenever you’d like. This was a larger hill to climb when it came to GD as none of the servers I have access to had PHP compiled with GD bundled, therefore giving me no access to imagerotate(). As reflected in the source, a function was written as an alternative, and appears to work just fine. It checks to see if imagerotate() is available before taking the extra CPU cycles doing it ‘by hand’.

Updates to the Cropper UI

I can’t credit Dave Spurr enough for his Cropper UI that powers the entire front end of the cropping mechanism this installation provides. He had made a number of updates after my version 1.0 release, so first things first I went ahead and upgraded to his most recent version.

The second most asked for feature was a specific alteration to the Cropper UI itself. Whether it be minimum dimensions, maximum dimensions, or something else, it seemed like many people would like to use the script, but the openness of the Cropper UI was in fact a limitation. I made an effort to indicate that Dave Spurr included many of the requested features right out the box and documented them well on his website. To help with the version 1.1 demo, I’ve included a few Cropper UI instances to demonstrate its robustness. When you check out the demo, you’ll see a new option to choose the crop type you’d like to use. I’ve included the following by default:

Basic crop
Includes the most basic version of the Cropper UI. Unrestricted as far as crop dimension is concerned.
Ratio (16:9)
A 16:9 ratio will be applied to the Cropper UI. There are no restrictions for width or height.
Minimum Dimensions (200×200)
The Cropper UI will require a minimum 200px by 200px crop area and will not allow anything less.
Minimum Dimensions (200×200) with Ratio (1:1)
The Cropper UI will require a minimum 200px by 200px crop area and will not allow anything less. It will also apply a 1 to 1 ratio when adjusting the crop area.
Maximum Dimensions (200×200)
The Cropper UI will require a maximum 200px by 200px crop area and will not allow anything less.
Maximum Dimensions (200×200) with Ratio (1:1)
The Cropper UI will require a maximum 200px by 200px crop area and will not allow anything less. It will also apply a 1 to 1 ratio when adjusting the crop area.
Fixed Dimensions (200×200)
You’re provided with a crop area at a fixed size of 200px by 200px. The drag handles are also removed as an added convenience.
Minimum Dimensions (100×100) & Maximum Dimensions (200×200)
With this option, you’re limited to a crop area range scaling from 100px by 100px to 200px by 200px.

The Cropper UI is quite impressive in and of itself as you can see by the number of options you can apply by changing some values. For example, one thing I didn’t include in the demo is a Cropper UI that is limited to minimum and maximum dimensions as well as an aspect ratio of 1:1. You can easily invoke a Cropper UI with these attributes by creating a new file (lib/init_cropper/min_max_ratio.js for example) and inserting the following:

function onEndCrop(coords, dimensions) {
	$('cropX').value = coords.x1;
	$('cropY').value = coords.y1;
	$('cropWidth').value = dimensions.width;
	$('cropHeight').value = dimensions.height;
}

Event.observe( window, 'load', function() {
	new Cropper.Img(
		'cropImage', {
			ratioDim: { x: 1, y: 1 },
			minWidth: 200,
			minHeight: 200,
			maxWidth: 300,
			maxHeight: 300,
			onEndCrop: onEndCrop
		}
	);
});

Swapping in this JavaScript would invoke a new Cropper UI for your image with a minimum dimension of 200px by 200px, a maximum dimension of 300px by 300px, as well as an aspect ratio of 1:1. Going further, you’re also able to specify a minimum or maximum for a height or width alone. This will result in a Cropper UI with handles only on the top and bottom if you wish. I would definitely suggest checking out the official website for Dave Spurr’s Cropper UI for more details

Download & installation instructions

Installation is very straightforward. Download links to follow.

  1. Download the GD or ImageMagick version
  2. Extract
  3. Upload to your webserver
  4. Give write permissions to the working folder and subfolders
  5. Begin using the demo

Download GD Crop and Resize v1.1 (.zip)

Download ImageMagick Crop and Resize v1.1 (.zip)

The demos and downloads have been removed temporarily due to a security issue. Replacements will be linked as soon as possible. Thank you for your patience. Please discontinue use as soon as possible until a revision has been posted.

Many times, if you’re experiencing odd behavior such as pages turning up blank, there is an issue with write permissions on your server. The demo will need write access to the directory in which it is stored as well as the working folder and all folders within it. Errors with the code itself will more than likely be output to the screen. If that happens, please feel free to post your errors at your earliest convenience.

What about AJAX?

Another request that popped up more than once was a request for an AJAX version, something that didn’t require the page to reload. I thought about working out something such as that but quickly dismissed it, at least for now. My intention with this project was to provide something which would be used by the widest audience possible. Too many times have I seen examples too far into their own development to prevent me from writing something from scratch. In my opinion, an AJAX version of this example would prevent easy adoption and inclusion for many developers. AJAX may be a possibility for a future version, but I’d like to seriously consider as many angles as possible. This directly relates to the (lack of) design when looking at the demonstration. I wanted to keep things minimal in order to create the least work for anyone who wants to try incorporating this into something they’ve written.

I hope at the very least, the GD version presents itself as useful to at least a few people over the coming months. I do plan continuing work on future version, I simply hope it doesn’t take as long as this revision has. Please provide any comments you’d like, especially bug reports, and enjoy the demo!

Copyright © 2006—2016 Jonathan Christopher