Resize image on the client side with JQuery

Reducing the upload sie by resizing image on the client side

Image resizing is considered as a server side operation as JavaScript and HTML were not so sophisticated and HTML5 support was not widely adopted for quite some time. even now, some features are not equally supported by all major browsers.

Anyhow, HTML5 is here to stay and over time we will get more and more features supported by all browsers.

Demanding operations which can be done in browsers but are not equally supported by browsers can be still used for the back-end applications (limited users access) where you can limit your client to use specific browser for the best performance and optimize your client side code to do it.

Recently I worked on a small web application project which main functionality is to handle image uploading and of course image resizing as I do not want to load full sized images while browsing the storage where images are uploaded. Even main image is resized to ensure I do not store images which are wider than 1024 pixels.

To make it reusable for future projects I refactor the code to use it as a JQuery plugin.

$.fn.ImageResize = function (options) {
var defaults = {
maxWidth: Number.MAX_VALUE,
maxHeigt: Number.MAX_VALUE,
onImageResized: null
}
var settings = $.extend({}, defaults, options);
var selector = $(this);
selector.each(function (index) {
var control = selector.get(index);
if ($(control).prop("tagName").toLowerCase() == "input" && $(control).attr("type").toLowerCase() == "file") {
$(control).attr("accept", "image/*");
$(control).attr("multiple", "true");
control.addEventListener('change', handleFileSelect, false);
}
else {
cosole.log("Invalid file input field");
}
});
function handleFileSelect(event) {
//Check File API support
if (window.File && window.FileList && window.FileReader) {
var count = 0;
var files = event.target.files;
for (var i = 0; i < files.length; i++) {
var file = files[i];
//Only pics
if (!file.type.match('image')) continue;
var picReader = new FileReader();
                picReader.addEventListener("load", function (event) {
                    var picFile = event.target;
                    var imageData = picFile.result;
                    var img = new Image();
                    img.src = imageData;
                    img.onload = function () {
                        if (img.width > settings.maxWidth || img.height > settings.maxHeigt) {
                            var width = settings.maxWidth;
                            var height = settings.maxHeigt;

                            if (img.width > settings.maxWidth) {
                                width = settings.maxWidth;
                                var ration = settings.maxWidth / img.width;
                                height = Math.round(img.height * ration);
                            }

                            if (height > settings.maxHeigt) {
                                height = settings.maxHeigt;
                                var ration = settings.maxHeigt / img.height;
                                width = Math.round(img.width * ration);
                            }

                            var canvas = $("<canvas/>").get(0);
                            canvas.width = width;
                            canvas.height = height;
                            var context = canvas.getContext('2d');
                            context.drawImage(img, 0, 0, width, height);
                            imageData = canvas.toDataURL();

                            if (settings.onImageResized != null && typeof (settings.onImageResized) == "function") {
                                settings.onImageResized(imageData);
                            }
                        }

                    }
                    img.onerror = function () {

                    }
                });
                //Read the image
                picReader.readAsDataURL(file);
            }
        } else {
            console.log("Your browser does not support File API");
        }
    }


}
    

Th plugin will simply take all images from file upload field, resize them and return resized base64 data in an event. You can simply take this data from event ad store it to hidden field and then simply post it to your backend.

    <input type="file" class="image-upload"/>
    <div class="images"></div>
    
       $(document).ready(function () {
            $(".image-upload").ImageResize(
                {
                    maxWidth: 800,
                    onImageResized: function (imageData) {
                        $(".images").append($("<img/>", { src: imageData }));
                    }
                });
        });
    

This will ensure that you do not upload large image files and waste data bandwidth.

You can checkout the demo at CodePen http://codepen.io/dejanstojanovic/full/qbXqYL/

The plugin source is also hosted on GitHub so you can fork it from https://github.com/dejanstojanovic/jQuery-ImageResize

References

Disclaimer

Purpose of the code contained in snippets or available for download in this article is solely for learning and demo purposes. Author will not be held responsible for any failure or damages caused due to any other usage.


About the author

DEJAN STOJANOVIC

Dejan is a passionate Software Architect/Developer. He is highly experienced in .NET programming platform including ASP.NET MVC and WebApi. He likes working on new technologies and exciting challenging projects

CONNECT WITH DEJAN  Loginlinkedin Logintwitter Logingoogleplus Logingoogleplus

.NET

read more

SQL/T-SQL

read more

Umbraco CMS

read more

PowerShell

read more

Comments for this article