You might be working on a project which has an image upload feature that takes images from the user and uploads it to your storage server. Once you have implemented it then you start thinking of optimizing it, so different factors like the format, quality, resolution, size of the image etc… come into consideration.
Later you decide to compress the images to save your storage space, so you implement an image compression feature in the back-end. Now you have saved your storage space. Don’t stop there because you can optimize more, save more resources like bandwidth and CPU cycles. If you have a server with limited resources and has many tasks to run then you are just adding more CPU load.
What if you can save your storage space, bandwidth and reduce server load at the same time. Yes, it is possible, the answer is “Compression at the client side using JavaScript”. Now let’s implement it.
Take advantage of the HTML5 Canvas that is used to draw graphics on a web page. Canvas is just a container for your graphics, JavaScript is used to draw.
Steps
Create an instance of JavaScript FileReader API.
const reader = new FileReader();
Read the input image using FileReader.
reader.readAsDataURL(sourceImage);
Create an instance of Image.
const img = new Image();
Set the result of the FileReader as source for the image.
img.src = event.target.result;
Create a HTML5 Canvas element
const elem = document.createElement("canvas");
Set the width and height of the canvas to match the new dimensions of the image.
elem.width = width; elem.height = height;
Create an object that is used to draw graphics on the canvas.
const ctx = elem.getContext("2d")
The getContext() method returns an object with the properties and methods required for drawing graphics on the canvas. The ‘2d‘ parameter limits us for drawing only 2D graphics.
Now draw the image on the canvas by specifying the position, width and height of the image.
ctx.drawImage(img, 0, 0, width, height);
Export the canvas as a blob or DataURL by specifying MIME type, image quality.
const data = ctx.canvas.toDataURL(img, mime, quality);
or
ctx.canvas.toBlob((blob) => { console.log(blob); //output image as a blob const file = new File([blob], fileName, { type: mime, lastModified: Date.now() }); //output image as a file }, mime, quality);
mime is the “mime type” of the image, like ‘image/jpeg’, ‘image/png’ .
Value of quality ranges from 0 to 1. It is the quality of the output image. If you don’t specify the mime and quality in the toBlob() method then default quality will be set and the mime type will be ‘image/png’.
The final code/* */ compress(e) { const width = 500; const height = 300; const fileName = e.target.files[0].name; const reader = new FileReader(); reader.readAsDataURL(e.target.files[0]); reader.onload = event => { const img = new Image(); img.src = event.target.result; img.onload = () => { const elem = document.createElement("canvas"); elem.width = width; elem.height = height; const ctx = elem.getContext("2d"); // img.width and img.height will contain the original dimensions ctx.drawImage(img, 0, 0, width, height); ctx.canvas.toBlob((blob) => { const file = new File([blob], fileName, { type: "image/jpeg", lastModified: Date.now() }); }, "image/jpeg", 1); }, reader.onerror = error => console.log(error); }; }Note:
If you want to maintain the aspect ratio of the output image then you can set either the width or height as constant and calculate the other dimension.
const width = 600; const scaleFactor = width / img.width; elem.width = width; elem.height = img.height * scaleFactor; ctx.drawImage(img, 0, 0, width, img.height * scaleFactor);
Here we kept width as constant and calculated the scaling factor. To find the relative height just multiply the scaling factor to the original height.
For browsers that don’t support “toBlob” methodUse this polyfill “https://developer.mozilla.org...” .
Modify the toBlob parameters as shown otherwise you will get “function expected” error.
//toBlob polyfill if (!HTMLCanvasElement.prototype.toBlob) { Object.defineProperty(HTMLCanvasElement.prototype, "toBlob", { value: function (callback, type, quality) { var dataURL = this.toDataURL(type, quality).split(",")[1]; setTimeout(function() { var binStr = atob( dataURL ), len = binStr.length, arr = new Uint8Array(len); for (var i = 0; i < len; i++ ) { arr[i] = binStr.charCodeAt(i); } callback( new Blob( [arr], {type: type || "image/png"} ) ); }); } }); } // toBlob usage ctx.canvas.toBlob(function (blob) { console.log(blob); //access blob here }, mimeType, quality);
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/102998.html
序 本文主要解析一下nginx ngx_http_gzip_module以及ngx_http_gzip_static_module中的gzip相關配置參數。 gzip 名稱 默認配置 作用域 官方說明 中文解讀 模塊 gzip gzip off; http, server, location, if in location Enables or disables gzipping of ...
摘要: GitHub Repo Widget showImg(https://travis-ci.org/hustcc/GitHub-Repo-Widget.js.svg?branch=master); showImg(https://img.shields.io/npm/v/github-repo-widget.js.svg?style=flat-square); showImg(http...
摘要:從現狀談及性能優化原文出處性能優化指南如今網絡發展迅猛,這對我們構建的互聯網平臺要求也更高。這就說明,我們在開發時,并沒有站在用戶的角度上換位思考,更別談性能優化。因此,我們可通過區分關鍵資源并調整加載的優先級來實現性能優化。 從web現狀談及性能優化 原文出處:《Karolina Szczur: The State of the Web》 性能優化指南The Internet is ...
摘要:從現狀談及性能優化原文出處性能優化指南如今網絡發展迅猛,這對我們構建的互聯網平臺要求也更高。這就說明,我們在開發時,并沒有站在用戶的角度上換位思考,更別談性能優化。因此,我們可通過區分關鍵資源并調整加載的優先級來實現性能優化。 從web現狀談及性能優化 原文出處:《Karolina Szczur: The State of the Web》 性能優化指南The Internet is ...
摘要:從現狀談及性能優化原文出處性能優化指南如今網絡發展迅猛,這對我們構建的互聯網平臺要求也更高。這就說明,我們在開發時,并沒有站在用戶的角度上換位思考,更別談性能優化。因此,我們可通過區分關鍵資源并調整加載的優先級來實現性能優化。 從web現狀談及性能優化 原文出處:《Karolina Szczur: The State of the Web》 性能優化指南The Internet is ...
閱讀 3152·2021-09-30 09:47
閱讀 2003·2021-09-22 16:04
閱讀 2274·2021-09-22 15:44
閱讀 2534·2021-08-25 09:38
閱讀 540·2019-08-26 13:23
閱讀 1221·2019-08-26 12:20
閱讀 2808·2019-08-26 11:59
閱讀 1077·2019-08-23 18:40