Ajax Image upload & Resize with PHP ImageMagick & jQuery

PHP GD library is more than enough for image processing, it supports numerous image formats and offers enough capabilities. But sometimes enough is not enough, sometimes we want to try out ImageMagick, just for the sake of performance, code clarity or just to explore more functionality. So today instead of using PHP GD, we are going to create an image upload and resize script using ImageMagick (PHP) and jQuery.

ImageMagick Installation

As you can see GD library is already included in PHP since 4.3. But ImageMagick is not always available for use, most web hosts do offer ImageMagick to their clients, but some don’t! So it’s better to confirm with yours whether they offer ImageMagick on their server. But if you only want to test it on localhost (Windows), you must install ImageMagick, you can follow these installation steps.

HTML file input box

Let’s create a basic HTML file input box for image upload. We just want to upload and resize image without refreshing the page, so we will be using jQuery Ajax to facilitate that later. Input field will be hidden here initially, as we will trigger click using jQuery which will trigger “open file” dialog box.

1
2
3
4
5
6
7
<h1>Ajax Image Upload with PHP ImageMagick</h1>
<div class="upload-wrapper">
<div class="upload-click">Click here to Upload File</div>
<div class="upload-image" style="display:none"><img src="images/ajax-loader.gif" width="16" height="16"></div>
<input type="file" id="input-file-upload" style="display:none" />
</div>
<div id="server-response"><!-- Json response from server --></div>

Upload page using HTML5 FileAPI & jQuery

As I mention earlier, user click on text inside upload-wrapper DIV element will open “file open” dialog box, which allows user to choose and upload files. Technique is simple; just using jQuery trigger().

1
2
3
$(".upload-click").click(function(e){
    $('#input-file-upload').trigger('click'); //trigger click
});

Once user selects a file, we can validate file format before uploading it to server using FileAPI

1
2
3
4
5
6
7
8
9
10
11
if(window.File && window.FileReader && window.FileList && window.Blob){
    oFReader = new FileReader(), rFilter = /^(?:image\/bmp|image\/cis\-cod|image\/gif|image\/ief|image\/jpeg|image\/jpeg|image\/jpeg|image\/pipeg|image\/png|image\/svg\+xml|image\/tiff|image\/x\-cmu\-raster|image\/x\-cmx|image\/x\-icon|image\/x\-portable\-anymap|image\/x\-portable\-bitmap|image\/x\-portable\-graymap|image\/x\-portable\-pixmap|image\/x\-rgb|image\/x\-xbitmap|image\/x\-xpixmap|image\/x\-xwindowdump)$/i;
    if(!rFilter.test(oFile.type))
        {
            alert('Unsupported file type!');
            return false;
        }
//Do other stuff   
}else{
    alert("Can't upload! Your browser does not support File API!");
}

And then using FormData object and jQuery, we can send file to server as Ajax request. Code below is simple example of posting file to server, but please remember to check Browser compatibility as old browsers do not support XMLHttpRequest 2 and FileAPI features.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var mdata = new FormData();
mdata.append('image_data', $("#input-file-upload")[0].files[0]);

jQuery.ajax({
    type: "POST", // HTTP method POST or GET
    processData: false,
    contentType: false,
    url: "upload_resize.php", //Where to make Ajax calls
    data: mdata, //Form variables
    dataType: 'json',
    success:function(response){
        $(".upload-image").hide();
        $(".upload-click").show();
       
        if(response.type == 'success'){
            $("#server-response").html('<div class="success">' + response.msg + '</div>');
        }else{
            $("#server-response").html('<div class="error">' + response.msg + '</div>');
        }
    }
});

Playing with ImageMagick

ImageMagick is very simple to use. It will resize, distort, crop, explode, blur and do many more on fly. There are various different things you can do with your image, and surprisingly you have less code to write and will look very neat.

Resize Image : For example, here’s how simple it is to resize your image using ImageMagick in PHP.

1
2
3
$image = new Imagick("myfile.jpg");
$image->resizeImage( 100, 100 , Imagick::FILTER_LANCZOS, 1, TRUE);
$image->writeImage("Upload_dir/new_image.jpg", true);

Resize Animated GIF : Some people face problem with Animated GIF in PHP GD, but with ImageMagick it’s not a problem. To resize animated GIF file, you can simply follow code below. It will resize your GIF file but keeping your animation intact.

1
2
3
4
5
6
7
$image = new Imagick("my_animation.gif");
$image = $image->coalesceImages();
foreach ($image as $frame) {
    $frame->resizeImage( $image_height , $image_width , Imagick::FILTER_LANCZOS, 1, TRUE);
}
$image = $image->deconstructImages();
$image->writeImages("Upload_dir/my_new_animation.gif", true); //notice writeImages();

PHP Resize Page

Let’s combine these two examples and create our PHP image resizing page. This will allow users to upload regular images as well as animated GIF files.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<?php
$upload_dir = "/imagemagick_upload/uploads/"; //path to upload dir
$upload_dir_url = "http://www.your_site.com/imagemagick_upload/uploads/"; //url to upload dir
$image_height = 300; //image height
$image_width = 300; //image width

//continue if $_POST is set and it is a Ajax request
if(isset($_POST) && isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest'){

    //makesure uploaded file is not empty
    if(!isset($_FILES['image_data']) || !is_uploaded_file($_FILES['image_data']['tmp_name'])){
               
                //generate a json response
                $response = json_encode(array(
                                            'type'=>'error',
                                            'msg'=>'Image file is Missing!'
                                        ));
                die($response);
        }
       
    //gets image size info from a valid image file
    $image_size_info  = getimagesize($_FILES['image_data']['tmp_name']);
   
    //get mime type from valid image
    if($image_size_info){
        $image_type = $image_size_info['mime']; //image type
    }else{
        $response = json_encode(array('type'=>'error', 'msg'=>'Invalid Image file !'));
        die($response);
    }
   
    //initiate ImageMagick
    $image = new Imagick($_FILES['image_data']['tmp_name']);
   
    if($image_type=="image/gif") //determine image format
    {
        //if it's GIF file, resize each frame
        $image = $image->coalesceImages();
        foreach ($image as $frame) {
            $frame->resizeImage( $image_height , $image_width , Imagick::FILTER_LANCZOS, 1, TRUE);
        }
        $image = $image->deconstructImages();
    }else{
        //otherwise just resize
        $image->resizeImage( $image_height , $image_width , Imagick::FILTER_LANCZOS, 1, TRUE);
    }
    //write image to a file
    $results = $image->writeImages($upload_dir. $_FILES['image_data']['name'], true);
   
    //output success response
    if($results){
        $response = json_encode(array('type'=>'success', 'msg'=>'Image Uploaded! <br /><img src="'.$upload_dir_url. $_FILES["image_data"]["name"].'">'));
        die($response);
    }
   
}

That’s all you need to create an Ajax based image uploader that uses PHP ImageMagick features to resize normal images as well as GIF animated images. If you want to resize images using regular PHP GD, read my another article here.

You can also checkout this step by step video created by Webucator below :

Download Demo

6 Comments Add Comment