故事:小魚最近寫了一個雲盤,容許他的同窗免費上傳一些圖片到雲盤之上。但是他最近發現服務器的某些服務怎麼都啓動不起來了。因而,他開始尋找緣由,最終發現是磁盤空間不足致使的。同窗們都上傳了啥啊?咋那麼快就沒內存了呢?小魚遠程鏈接上服務器,將其中的圖片拖到本地查看,不看不知道,一看嚇一跳,全是各位「老師」的照片啊!啥波多野結衣、蒼井空...應有盡有,全是高清無碼大圖!小魚看了老久才晃過神,擦了擦嘴角的哈喇子。這怎麼行,雖然圖片很好看,可是它養分也跟不上啊!必須得限制。javascript
因而小魚決定讓圖片迴歸它應有的畫質,懷着厚重的心情寫下了圖片壓縮工具。html
/** * @file 圖片壓縮(轉換)工具 v1.0.0 * * @author xiangchengyu<x555666777@qq.com> * * Date: 2019-09-06 23:30 */
(function() {
var core_version = '1.0.0';
var _ImageConversion = function() {};
_ImageConversion.prototype = {
version: core_version,
constructor: _ImageConversion,
img2Canvas: function(image, config) {
if (!image || typeof image !== 'object') return ;
if (typeof config !== 'object') {
throw new Error('The second parameter must be an object.');
}
var cvs = document.createElement('canvas');
var ctx = cvs.getContext('2d');
cvs.width = image.width;
cvs.height = image.height;
if (!config.scale) {
config.width = Number(config.width);
config.height = Number(config.height);
cvs.width = config.width || config.height * image.width / image.height || image.width;
cvs.height = config.height || config.width * image.height / image.width || image.height;
} else {
config.scale = Number(config.scale);
cvs.width = config.scale > 0 && config.scale < 10 ? cvs.width * config.scale : image.width;
cvs.height = config.scale > 0 && config.scale < 10 ? cvs.height * config.scale : image.height;
}
ctx.drawImage(image, 0, 0, cvs.width, cvs.height);
return cvs;
},
canvas2DataURL: function(canvas, quality, type) {
if (!_isSupportImage(type)) {
type = 'image/jpeg';
}
return canvas.toDataURL(type, quality);
},
canvas2Blob: function(canvas, quality, type) {
return new Promise(resolve => {
canvas.toBlob(blob => { resolve(blob) }, type, quality);
});
},
file2DataURL: function(file) {
return new Promise(resolve => {
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onloadend = e => resolve(e.target.result);
});
},
dataURL2Img: function(dataURL) {
return new Promise((resolve, reject) => {
var image = new Image();
image.src = dataURL;
image.onload = () => resolve(image);
image.onerror = () => reject(new Error('DataURL conversion to image failed.'));
});
},
dataURL2Blob: function(dataURL, type) {
var arr = dataURL.split(',');
var mime = arr[0].match(/:(.*?);/)[1];
var bstr = atob(arr[1]);
var n = bstr.length;
var u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
if (_isSupportImage(type)) {
mime = type;
}
return new Blob([u8arr], { type: mime });
},
blob2File: function(blob, filename, options = { type: 'image/jpeg' }) {
return new File([blob], filename, options);
},
url2Img: function(url) {
return new Promise((resolve, reject) => {
var image = new Image();
image.src = url;
image.onload = () => resolve(image);
image.onerror = () => reject(new Error('Image failed to load, please check the image URL.'));
});
}
};
var _isSupportImage = function(type) {
return ['image/jpeg', 'image/png', 'image/gif'].some(item => item === type);
};
window.ImageConversion = (function() {
return new _ImageConversion();
})();
})();
複製代碼
使用的時候看起來很複雜,其實否則,之因此沒有進一步封裝是由於咱的瀏覽器不支持 async/await ,很差操做。咱也不想用 babel 轉。那咋辦呢?偷個懶唄,等學會如何手寫 async/await 後再來更新。java
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>ImageConversion</title>
<script src="scripts/conversion.js"></script>
</head>
<body>
<input id="file" type="file" name="uploadImage" onchange="getCompressFile()" />
<div id="preview" class="preview"></div>
<script> function getCompressFile() { var file = document.getElementById('file').files[0]; console.log(file); var config = { width: 300, height: 200, scale: 1, quality: .8, type: 'image/jpeg' }; var compress = (function() { ImageConversion.file2DataURL(file).then(dataURL => { ImageConversion.dataURL2Img(dataURL).then(image => { var cvs = ImageConversion.img2Canvas(image, config); ImageConversion.canvas2Blob(cvs, config.quality, config.type).then(blob => { console.log(blob); var file = ImageConversion.blob2File(blob, 'filename', {type: config.type}); ImageConversion.file2DataURL(file).then(result => { console.log(result); }); // TODO }); }); }); })(); } </script>
</body>
</html>
複製代碼