Why use JavaScript FileReader API to resize images?
Many online image resizing tools, that I have come across, first load the images on a remote server, and then 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 relatively slow.
Most importantly, if your website still uses http instead of https (secured protocol), mordern browsers will 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 will allow my users to process multiple images 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.
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 assigned the multiple property to the file input type element (since 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> <p id="img"></p> <!--show the images--> </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>
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).
The readAsDataURL() method is used to read the contents of the specified Blob or File. Learn more about this method here.
reader.readAsDataURL(this);
Example 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.
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> <body> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script> <p>Resize Image to: <input type="text" style="width:50px;" value="50" id="size" /> % </p> <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>
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.
That’s it.
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.