Front End Picture Compression

When I developed a web project two years ago, our team could only use the thrid part to clip and compress the picture which users upload, in order to make the picture smaller and easy to be stored in the database. Actually, if you took this step before in your own projects, you would find its so inefficient and more worse is we have to add a middleware in front end or back end to limit the size. From my stand, the step doing like this has no technical content but which you have to do in your project. But now, we can use Canvas to help us! Actually, if you learn it well, the Canvas could handle all picture operations in the front end, no exaggeration. The picture compression is just a small case.

1. Process

(1) The user uploads one picture. (2) Use "FileReader" API to get the picture. (3) Create a Canvas element. (4) Use "drawImage", put the picture into Canvas element. (5) Scaling picture. (6) Use "toBlob" or "toDataURL" to change Canvas object to picture object. (7) Upload the picture.

2. Code

(1) Initial objects:
// Omit create file input var fileinput = document.querySelector("input"); // get the file input var filereader = new FileReader(), img = new Image(); var file = null; var canvas = document.createElement("canvas"); // Do not add it to document, we don't want it show var context = canvas.getContext("2d");
(2) Get user picture.
filereader.onload = function(e) { img.src = e.target.result; }; fileinput.addEventListener("change", function (e) { file = event.target.files[0]; if (file.type.indexOf("image") === 0) { filereader.readAsDataURL(file); } });
(3) Scaling picture
img.onload = function () { var originWidth = this.width; var originHeight = this.height; var maxWidth = 200, maxHeight = 200; var targetWidth = originWidth, targetHeight = originHeight; // More than 200 if (originWidth > maxWidth || originHeight > maxHeight) { // Change picture based on its height or width if (originWidth / originHeight > maxWidth / maxHeight) { targetWidth = maxWidth; targetHeight = Math.round(maxWidth * (originHeight / originWidth)); } else { targetHeight = maxHeight; targetWidth = Math.round(maxHeight * (originWidth / originHeight)); } } // Scaling picture canvas.width = targetWidth; canvas.height = targetHeight; context.clearRect(0, 0, targetWidth, targetHeight); // Put picture in Canvas object context.drawImage(img, 0, 0, targetWidth, targetHeight); }
(4) Change to Blob object and upload by Ajax
// This code also belongs to img.onlad function. canvas.toBlob(function (blob) { var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function() { if (xhr.status == 200) { // Do something } }; xhr.open("post", "xxx", true); xhr.send(blob); }, file.type || "image/png");
If you want to learn "toBlob" and "toDataURL" function, just click here. These two function belong to Canvas, and their function is change Canvas object to binary file so that we can upload or download the picture.
(That's all)