Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Preview and Crop Before Upload

DZone's Guide to

Preview and Crop Before Upload

· Web Dev Zone
Free Resource

Add user login and MFA to your next project in minutes. Create a free Okta developer account, drop in one of our SDKs to your application and get back to building.

DEMO

Further to our earlier post about drag and drop uploads, we have managed to add some additional features to this. HTML5 allows a user to preview an image before it is uploaded to the server. In a typical web environment, the image needs to adhere to a certain width to height ratio to fit in a particular slot. This becomes a necessity in slideshows, galleries or tightly designed pages. The script below, allows you to crop an image to a given prescribed width to height ratio. The beauty of the script is that it allows you to crop only part of the original image. For example, if you need an image of 400 px width and 200 px height and your original uploaded image is 1000 px wide and 1000 px in height, it will allow you to choose a part of the image and resize it to 400 x 200. This effectively means you can choose an area of 400 x 200 of the original image or 800 x 400 of the original (which is scaled to 400 x 200 post resize) and so on. It will never allow a crop which doesn’t satisfy the above width to height ratio. Similarly it will not allow you to choose a part of the image lesser than 400 x 200.

Click here to view a demo of drag and drop file upload. Once the files are in queue, you have the option of cropping the image before uploading. The files that you upload will show up from the server once the upload is finished. A brief explanation on how we have tackled this.

For the demo, we shall be using Andrew Valums’ Ajax Upload which can be found at http://valums.com/ajax-upload/ and imgAreaSelect which can be found at http://odyniec.net/projects/imgareaselect/.

We added a few more parameters to be used by the Drag and Drop upload script which is used for cropping the queued images.

$(document).ready(function () {
    uploader = new qq.FileUploader({
        element: document.getElementById('fileuploader'),
        folderName: 'uploads',
        action: 'upload.php',
        //Files with following extensions are only allowed
        allowedExtensions: ['gif','jpg','jpeg','png','txt'],
        showCropTool: 1,
        sizeLimit: 10737418240, // Maximum filesize limit which works without any problems is 30MB. Current limit is set to 10MB = 10 * 1024 * 1024
        params: {
            'uploadedBy': 'Sapnagroup',
            'x1': '0',  // x coordinates of the image
            'y1': '0',      // x coordinates of the image
            'x2': '300',    // x coordinates of the image
            'y2': '150',    // y coordinates of the image
            'cWidth': '300',        // required crop width
            'cHeight': '150',       // required crop heignt
            'oWidth': '800',        // width of the crop preview image
            'oHeight': '600',       // height of the crop preview image
            'rWidth': '300',        // resize width
            'rHeight': '150'        // resize height
        },
        onSubmit: function(id, fileName){
 
        },
        onComplete: function(id, fileName, responseJSON){ // Customize the output sent to responseJSON in demo.php
            resetParams();
 
            switch(responseJSON.ext){
                case 'gif':
                case 'jpg':
                case 'jpeg':
                case 'png':
                var imageHTML = '
<div style="margin: 0 10px 0 0;"><img src="%27%20+%20responseJSON.thumbnailPath%20+%20%27" alt="" border="0" width="75">
' + fileName + ' uploaded by ' + responseJSON.uploadedBy + '</div>
 
';
                document.getElementById('imageThumbnails').innerHTML = document.getElementById('imageThumbnails').innerHTML + imageHTML;
                break;
                default:
                // Do nothing
                break;
            }
 
            if(uploader._filesInProgress < 1){
                document.getElementById('message').innerHTML = "All files have been uploaded. The page will refresh itself in 10 seconds."
                // var t = setTimeout('location.href = location.href;', 10000)
            }
        }
    });
});
 
var uploader;
 
// Function to update the parameters once a crop region is selected
function updateParams(img, selection){
    uploader.setParams({
        'x1': selection.x1,
        'y1': selection.y1,
        'x2': selection.x2,
        'y2': selection.y2,
        'cWidth': selection.width,
        'cHeight': selection.height,
        'oWidth': img.width,
        'oHeight': img.height,
        'rWidth': '300',
        'rHeight': '150'
    });
}
 
// Function to reset all parameters
function resetParams(){
    uploader.setParams({
        'x1': '0',
        'y1': '0',
        'x2': '300',
        'y2': '150',
        'cWidth': '300',
        'cHeight': '150',
        'oWidth': '800',
        'oHeight': '600',
        'rWidth': '300',
        'rHeight': '150'
    });
}

We also made a few changes to fileuploader.js, which you can find in the source which is available for download at the end of this post. Particularly important is line number 811. We initialize the crop tool for each image that has been queued for upload and when a crop selection is made we just update the crop selection to used in our server side script using the ‘updateParams’ function.

$('#img_' + item.qqFileId).imgAreaSelect({ parent: '#cropDiv_' + item.qqFileId, x1: self._options.params.x1, y1: self._options.params.y1, x2: self._options.params.x2, y2: self._options.params.y2, persistent: true, resizable: true, onSelectChange: updateParams, parent : self._options.params.parent, minWidth: self._options.params.cWidth, minHeight: self._options.params.cHeight, aspectRatio: self._options.params.cWidth + ':' + self._options.params.cHeight, handles: true, zIndex: 1 });

On the server side we can use the parameters to crop and resize the image. Below is the code used in PHP:

// Get dimensions of the original image
list($currentWidth, $currentHeight) = getimagesize($result['path']);
 
// The x and y coordinates on the original image where we will begin cropping the image
$left = $_GET['x1'] * ($currentWidth / $_GET['oWidth']);
$top = $_GET['y1'] * ($currentHeight / $_GET['oHeight']);
 
// This will be the final size of the image (e.g. how many pixels left and down we will be going)
$cropWidth = $_GET['cWidth'] * ($currentWidth / $_GET['oWidth']);
$cropHeight = $_GET['cHeight'] * ($currentHeight / $_GET['oHeight']);
 
// Crop the image
$canvas = imagecreatetruecolor($cropWidth, $cropHeight);
$currentImage = imagecreatefromjpeg($result['path']);
imagecopy($canvas, $currentImage, 0, 0, $left, $top, $currentWidth, $currentHeight);
imagejpeg($canvas, $result['path'], 100);
 
// Get dimensions of the cropped image
list($currentWidth, $currentHeight) = getimagesize($result['path']);
 
// Resize the image
$canvas = imagecreatetruecolor($_GET['rWidth'], $_GET['rHeight']);
$currentImage = imagecreatefromjpeg($result['path']);
imagecopyresampled($canvas, $currentImage, 0, 0, 0, 0, $_GET['rWidth'], $_GET['rHeight'], $currentWidth, $currentHeight);
imagejpeg($canvas, $result['path'], 100);

Download the full source here.

Launch your application faster with Okta’s user management API. Register today for the free forever developer edition!

Topics:

Published at DZone with permission of Sapna Group, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}