Resize images on your Browser using FileReader API and HTML5 Canvas

← PrevNext →

The Bulk image resizer tool that I have created, allows users to resize multiple images quickly. Not only fast, this tool has another important feature, it resizes images without loading the images on any server. It does everything on your browser. This makes the process safe and secure. Here, I’ll show you how you too can create a similar tool to resize an image on your computer using JavaScript FileReader API and HTML5 Canvas element.

FileReader API with HTML5 Canvas and jQuery

See this demo

Why use JavaScript FileReader API to resize images?

Many online image resizing tools, that I have come across, load the images on a remote server, as it process the images at the server side. This requires space (to store the images), you have to write server side code to monitor the process, remove the images after some time, and this can sometimes create security issues. The entire process is relative slow and less secure.

Most importantly, if your website still uses http instead of https (secured protocol), the new updated browsers would show a Not secure message on the browser's address bar.

To overcome these issues, I started looking for a better solution and I came across the FileReader API, which allow users to process images (multiple of course) on their computer itself, without having to upload the images to a server. This is good. While digging more, I found that I could even quickly resize the images on my browser itself, without too much hassle.

Let’s see how it works.

The FileReader API provides the necessary properties and methods to read a file and uses the File API to get all the information of a selected file. Its works in sync with input[type=file] element.

Here in this post I’ll show you two examples using FileReader API and input[type=file] element. The first example shows you how to read an image (or multiple images) selected using file input element and show it on the browser without having to store it on the server.

The Second example extends the first and here I’ll show you how to resize the selected images.

1) The Markup with the Script

All I need is two elements on my web page. One is the input file element and the second is <p> element, to show the selected images.

I have added the multiple property to the file input type element (as it will allow me to choose multiple files).

<html>
<head>
    <title>Read Multiple Image using file Input Element</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
</head>

<body>
    <p>Click button to select files.</p> 
    <p><input type="file" id="file" multiple /></p>

    <!--SHOW THE IMAGES-->
    <p id="img"></p>
</body>

<script>
    $(document).ready(function () {

        $('#file').change(function () {
            if (this.files.length > 0) {

                $.each(this.files, function () {
                    var reader = new FileReader();

                    reader.onload = function (e) {
                        var img = new Image();
                        img.src = e.target.result;

                        img.setAttribute('style', 'width:auto;');    // you can adjust the image size by changing the width value. 
                        $('#img').append(img);
                    };
                    reader.readAsDataURL(this);
                });
            }
        });
    });
</script>
</html>
Try it

The script above executes when a user selects images from the computer. The file input element's change event immediately checks if the user has selected any files and if yes, it loops through each file (images).

Also Read: Loop through Elements, Arrays and Objects using jQuery .each() Function

The readAsDataURL() method is used to read the contents of the specified Blob or File. Learn more about this method here.

reader.readAsDataURL(this);

2) Using FileReader API with HTML5 Canvas

Now let’s see our next example, where I’ll show you how to resize the images using the API and input file type. In-addition, I need an HTML5 Canvas element to complete the resize process. I’ll create the Canvas element dynamically in the script section.

The Markup

I have added another input element of type text on my web page. The remaining elements are the same as seen in the first example. The text box will allow users to add a number (for percentage) required to resize the images.

I have included few more lines in the script for resizing the selected images.

<html>
<head>
    <title>Using FileReader API with HTML5 Canvas</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
</head>
<body>
    Resize Image to: <input type="text" style="width:50px;" value="50" id="size" /> %

    <p><input type="file" id="file" multiple /></p>
    <p id="img"></p>
</body>

<script>
    $(document).ready(function () {
        $('#file').change(function () {
            if (this.files.length > 0) {

                $.each(this.files, function (i, v) {
                    var reader = new FileReader();

                    reader.onload = function (e) {
                        var img = new Image();
                        img.src = e.target.result;

                        img.onload = function () {

                            // CREATE A CANVAS ELEMENT AND ASSIGN THE IMAGES TO IT.
                            var canvas = document.createElement("canvas");

                            var value = $('#size').val();

                            // RESIZE THE IMAGES ONE BY ONE.
                            img.width = (img.width * value) / 100
                            img.height = (img.height * value) / 100

                            var ctx = canvas.getContext("2d");
                            ctx.clearRect(0, 0, canvas.width, canvas.height);
                            canvas.width = img.width;
                            canvas.height = img.height;
                            ctx.drawImage(img, 0, 0, img.width, img.height);

                            $('#img').append(img);      // SHOW THE IMAGES OF THE BROWSER.

                            // AUTO DOWNLOAD THE IMAGES, ONCES RESIZED.
                            var a = document.createElement('a');
                            a.href = canvas.toDataURL("image/png");
                            a.download = 'sample.jpg';
                            document.body.appendChild(a);
                            a.click();
                        }
                    };
                    reader.readAsDataURL(this);
                });
            }
        });
    });
</script>
</html>
Try it

The script loops through each image (if multiple images), the FileReader reads the images and once the image is loaded, it will assign the image to the dynamically created Canvas element. This is where the code gets the percentage (%) value from the user input and draws the image on the Canvas using the percentage value. Finally, it automatically downloads the images by creating an <a> (anchor) element.

See this demo

That’s it.

Conclusion

The procedure that I have shared here is one of the fastest and the most efficient way to reduce or resize multiple images online. You do not have worry about the space required on the server to store the images for processing. Does’nt matter if your internet speed is less or more, as this method doesn’t require transferring of files from one end to another. In-addition no more security concerns at the server side.

However, I am stuck with one little problem with the above method. How do I compress all the images together before download? You know, like creating a ZIP file. I am sure I’ll find a suitable solution for this too. If you have found an answer already to this issue, you can share it with use here. Simply leave your message below.

Thanks for reading.

← PreviousNext →