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

Published 6 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!

There's a conversation brewing

  1. Well done on getting this version sorted Jonathon, theres alot of work gone into it. Its really shaping up into a useful script :-)

    Just incase people have downloaded this before Jonathan gets to update the download package there is a small error in crop_image.php where jpgs are not uploading and the file type is not jpeg error showing.

    to fix it simply open crop_image.php and replace the line:
    if($_FILES['image']['type']=”image/=jpeg”) {

    with:
    if($_FILES['image']['type']=”image/pjpeg”) {

    Other than that the rest appears to be working pefectly, no problems with Windows servers any more either, works exactly as per the Demo.

    Good Work Jonathon :-)

  2. Just an idea… or question…

    1. crop by dimensions.. ie.. I would do 4×3
    2. Then instead of going to the image resize page, could it be automatically resized proportionately to a given max size?

  3. Wow, How did I miss this a year ago ? Brilliant download. Could come in really handy for an app I’m working on at the moment.

  4. I love your script. I have modded it for my site so that when you crop it, the original file is deleted. But, if someone uploads a file and exits without cropping it, the file won’t get deleted.

    Is there a way to crop and resize without uploading the initial file? Like use a temporary file or something. Or, to automatically delete uploads after a certain time like in the demo.

    Thanks

  5. there is a proplem in upload and i get the solution and is change

    ($_FILES["image"]["type"] == “image/jpeg”)
    || ($_FILES["image"]["type"] == “image/pjpeg”)
    in crop_image.php file to become
    if(($_FILES["image"]["type"] == “image/jpeg”)
    || ($_FILES["image"]["type"] == “image/pjpeg”))
    to uploade any jpg image

  6. @Paul: Thank you for the great catch, I’m going to update the download as soon as I can find the extra few minutes.

    @Mike: Thanks very much, I hope you’re able to use it effectively, please keep in mind Paul’s find above.

    @Smithy: Thank you. Yes, it is indeed possible (as reflected by the live demo). There are a few ways to do it, and it will probably be best for you if you customized your installation. As an overview, I bypassed the upload process by hard coding the source image path and used that in place of the PHP that handles moving the (temporary) uploaded file to a permanent location. The rest of the demo should work as written.

    @mohamed: You and Paul are on the same wavelength, I really need to get the download updated ASAP.

  7. I just find a bug, change the line 31 on file resize_image.php with this:

    if($imageWidth != $cropWidth || $imageHeight != $cropHeight)

    Nice script btw :)

  8. @OXODesign: Thank you very much for posting your findings!

  9. Can anyone help me integrate a link upload to crop images and resize them?

  10. @Dennis: I’m not sure I follow your request. You’d like to simply create a link to the upload form?

  11. hi

    this is really a great script and it is so easy to use!

    I just have one question: I tried modifying the max image size to 4MB from 1MB and when I try uploading a 3MB image I still get the same message: “image size is more than 50k”.

    Could I have some help getting that fixed ?

    thank you very much !

  12. nevermind, I fixed it

By all means, contribute

Leave a comment

Powered by Fusion

This article is so meta

Published December 17th, 2007

Random article

css.php