Crop and Resize Images with ImageMagick

Share this article

If your website allows users to upload photos, image cropping/resizing functionality certainly comes in handy. But users might not have access to image manipulation tools like Photoshop, so by providing a cropping/resizing feature you can allow users to upload photos from any device (e.g. tablets or phones) without them having to worry about the the final size. Furthermore, you can create different versions of the same image and also allow users to crop specific portions of uploaded picture. In this article I’ll show you how to create an image cropping tool with the help of the ImageMagick PHP extension. This tutorial assumes that you already have the extension installed, so if not then be sure to read the manual.

Getting Familiar

The ImageMagick extension performs image processing using the ImageMagick library. ImageMagick provides a lot of API methods through which you can manipulate an image. It offers a simple object-oriented interface to use the API; you just need to create an instance of the Imagick class and then call the appropriate methods to start manipulating the images. Since we’re going to create an image cropper, we’ll mostly be using the two methods: cropImage() and thumbnailimage().

cropImage

The cropImage() method accepts four arguments. The first two arguments indicate the height and width of the cropped region, and the last two indicate the X and Y coordinates of the top-left corner of the cropped area. For example:
<?php
$inFile = "test.jpg";
$outFile = "test-cropped.jpg";
$image = new Imagick($inFile);
$image->cropImage(400,400, 30,10);
$image->writeImage($outFile);
We create an Imagick object first, passing to its constructor the filename of our image. Then we call cropImage() with appropriate arguments. In this case the code will produce a cropped image of size 400×400px starting at 30px from the top and 10px in from the left of the original image. Finally, writeImage() saves the result back to disk for us.

thumbnailImage

The thumbnailImage() method simply accepts the height and width of the resized image and can be used as follows:
<?php
$inFile = "test.jpg";
$outFile = "test-thumbnail.jpg";
$image = new Imagick($inFile);
$image->thumbnailImage(200, 200);
$image->writeImage($outFile);
The above code produces a 200×200px version of image. If either the width or height argument to thumbnailImage() is set as 0, the aspect ratio is maintained. We can also pass a third argument known as bestfit; If this is set true, the image will be resized in such a way that the new dimensions can be contained within the height and width specified. For example, a call to thumbnailImage(400, 400, true) on a 1200×768px image will produce a 400×200px version. The new dimensions are less than or equal to the specified dimensions. Now that you’re familiar with the two methods, we’re good to go.

Upload and Cropping

Of course we’ll need to create an HTML form with which users can upload photos:
<form action="upload.php" method="post" enctype="multipart/form-data">
 <label for="file">Image:</label>
 <input type="file" name="file" id="file"><br>
 <input type="submit" name="submit" value="Upload and Crop">
</form>
As soon as the user hits the upload button a POST request will be sent to a script which will handle the file upload process and show the uploaded image to the user for cropping. Remember, when uploading files you need to set the form’s enctype
attribute to “multipart/form-data”. An upload script handles the image upload and resizing the image if required.
<?php
if (isset($_FILES["file"])) {
    $tmpFile = $_FILES["file"]["tmp_name"];
    $fileName = ... // determine secure name for uploaded file

    list($width, $height) = getimagesize($tmpFile);
    // check if the file is really an image
    if ($width == null && $height == null) {
        header("Location: index.php");
        return;
    }
    // resize if necessary
    if ($width >= 400 && $height >= 400) {
        $image = new Imagick($tmpFile);
        $image->thumbnailImage(400, 400);
        $image->writeImage($fileName);
    }
    else {
        move_uploaded_file($tmpFile, $fileName);
    }
}
You should be very careful while accepting files from users as someone can upload a malicious file to your server if you don’t create a secure upload system. For more information, read the article File Uploads with PHP, paying special attention to the “Security Considerations” section. The getimagesize() function returns a null height and width if the file is not an image, so if the code detects the file is not an image, it simply redirects the user elsewhere. Additionally, you can also check the image type and size of the file using getimagesize(), but in this case we just check if the file is an image based on the null values. Since the script already knows the width and height of the uploaded image at this point, it can determine whether the image should be resized down. If dimensions are more than 400×400px, it’s resized to create a 400×400px thumbnail by calling thumbnailImage(). As I explained earlier, the method takes two parameters: width and height. If you want to maintain the image’s aspect ratio, it’s recommended to pass 0 as one of the arguments. Finally, the resized image is saved by calling writeImage(), or moved with move_uploaded_file() if it was already a suitable size. The saved image is outputted to the browser so that the user gets a chance to crop it. To allow users to select specific portion of the image, I use a jQuery plugin called ImageAreaSelect. To use the plugin, the jQuery library needs to be available, as well as the plugin’s CSS and JavaScript files.
<script type="text/javascript" src="scripts/jquery.min.js"></script>
<script type="text/javascript" src="scripts/jquery.imgareaselect.pack.js"></script>
<link rel="stylesheet" type="text/css" href="css/imgareaselect-default.css">
To initialize the plugin you can use the following code:
selection = $('#photo').imgAreaSelect({
    handles: true,
    instance: true
});
#photo is the id of the image shown to the user. By setting the handles property true you can show resize handles on the selection area, and instance true gets an instance and save it to the variable selection. It’s through selection that you can easily retrieve the selection area later when the user finalizes his cropping. getSelection() gives you everything you need. For example, getSelection().width gives you the width of the selection area. Similarly, you can use getSelection().x1 and getSelection().y1
to find the coordinates of the top left-corner of the selection area. Putting this all together in a page, you’ll most likely register an onclick callback to a link or button, which the user can click to finalize his selection. When the button is clicked, the selection area width, height, and top-left corner coordinates is retrieved.
$("#crop").click(function(){
    var s = selection.getSelection();
    var width = s.width;
    var height = s.height;
    var x = s.x1;
    var y = s.y1;
    ...
});
An Ajax request is sent to a cropping script, passing these values as request parameters since they are needed to crop the image through ImageMagick. Additionally, you’ll want to send the image name since the script will need to know the name of the image that it will be cropping.
var request = $.ajax({
    url: "crop.php",
    type: "GET",
    data: {
        x: x,
        y: y,
        height: height,
        width: width,
        image: $("#photo").attr("src")
    }
});
When the request finishes, the image is reloaded so that the new cropped version will be shown in place of the old image.
request.done(function(msg) {
    $("#photo").attr("src", msg);
    selection.cancelSelection();
});
When cropping is done, the request returns the name of the cropped image, and the new image is loaded by changing the src attribute. So what does the cropping script look like?
<?php
$file = basename($_GET["image"]);
$cropped = "cropped_" . $file;
$image = new Imagick($file);
$image->cropImage($_GET["width"], $_GET["height"], $_GET["x"], $_GET["y"]);
$image->writeImage($cropped);
echo $cropped;
The script first extracts the name of the image that needs to be cropped; the image name will be a full URL in the form of http://example.com/path/image.jpg, but only the image.jpg part is needed. Next, the string “cropped” is prefixed to the original name so that it will look like cropped_image.jpg. This allows the cropped image to be saved without overwriting the original. The cropImage() method is used to crop the original image using the four parameters related to the selection area that were sent to the script, and then the cropped image is saved to the new file. The name of the cropped image is then echoed back to the Ajax request for display in the browser.

Conclusion

In this article I created a simple cropping tool to show you the power and easy of use of the ImageMagick extension. You can learn more about it, and be creative and make something more useful using its powerful API. For instance, if you wanted to extend what I’ve presented here, you could give users the option to download their images in multiple sizes. Sample code to accompany this article is available on GitHub to get you started. Image via Fotolia And if you enjoyed reading this post, you’ll love Learnable; the place to learn fresh skills and techniques from the masters. Members get instant access to all of SitePoint’s ebooks and interactive online courses, like Jump Start PHP. Comments on this article are closed. Have a question about PHP? Why not ask it on our forums?

Frequently Asked Questions (FAQs) about Cropping and Resizing Images with ImageMagick

How can I install ImageMagick on my system?

ImageMagick is a powerful software suite that can be used to manipulate images in various ways, including cropping and resizing. To install ImageMagick, you can download it directly from the official website. Once downloaded, follow the installation instructions provided. It’s available for various operating systems including Windows, Linux, and macOS. Remember to check the system requirements before installation to ensure compatibility.

Can I use ImageMagick to crop images in different shapes?

Yes, ImageMagick is versatile and allows you to crop images in various shapes. You can crop images in rectangular, circular, or any other shape by specifying the appropriate parameters in the command line. The ‘convert’ command is used for this purpose. For instance, to crop an image into a circle, you can use the ‘-crop’ option followed by the dimensions of the circle.

How can I resize an image without losing its quality?

ImageMagick provides several options for resizing images without losing quality. The ‘-resize’ option can be used to change the dimensions of an image while maintaining its aspect ratio. If you want to resize the image to a specific width or height, you can use the ‘-scale’ option. Remember to save the resized image under a different name to preserve the original image.

Can I use ImageMagick to convert image formats?

Yes, ImageMagick supports a wide range of image formats and can be used to convert images from one format to another. The ‘convert’ command is used for this purpose. For instance, to convert a JPEG image to PNG, you can use the command ‘convert image.jpg image.png’.

How can I crop an image to a specific size using ImageMagick?

To crop an image to a specific size, you can use the ‘-crop’ option followed by the dimensions of the desired size. For instance, to crop an image to a size of 200×200 pixels, you can use the command ‘convert -crop 200×200+0+0 image.jpg cropped_image.jpg’.

Can I use ImageMagick to edit images in bulk?

Yes, ImageMagick allows you to edit images in bulk. This can be done using the ‘mogrify’ command, which modifies images in place. For instance, to resize all JPEG images in a directory to a width of 800 pixels, you can use the command ‘mogrify -resize 800x *.jpg’.

How can I add borders to an image using ImageMagick?

ImageMagick provides the ‘-border’ option to add borders to an image. You can specify the width and color of the border. For instance, to add a 5-pixel wide black border to an image, you can use the command ‘convert -border 5 -bordercolor black image.jpg bordered_image.jpg’.

Can I use ImageMagick to create thumbnails of images?

Yes, ImageMagick can be used to create thumbnails of images. The ‘thumbnail’ option can be used for this purpose. For instance, to create a thumbnail of an image with a width of 100 pixels, you can use the command ‘convert -thumbnail 100x image.jpg thumbnail.jpg’.

How can I rotate an image using ImageMagick?

ImageMagick provides the ‘-rotate’ option to rotate images. You can specify the angle of rotation. For instance, to rotate an image 90 degrees clockwise, you can use the command ‘convert -rotate 90 image.jpg rotated_image.jpg’.

Can I use ImageMagick to add text to an image?

Yes, ImageMagick allows you to add text to an image. This can be done using the ‘annotate’ option. You can specify the position, font, size, and color of the text. For instance, to add the text “Hello” to an image, you can use the command ‘convert -annotate +30+30 ‘Hello’ image.jpg text_image.jpg’.

Sandeep PandaSandeep Panda
View Author

Sandeep is the Co-Founder of Hashnode. He loves startups and web technologies.

Intermediate
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week