JavaScript 圖片壓縮工具

故事:小魚最近寫了一個雲盤,容許他的同窗免費上傳一些圖片到雲盤之上。但是他最近發現服務器的某些服務怎麼都啓動不起來了。因而,他開始尋找緣由,最終發現是磁盤空間不足致使的。同窗們都上傳了啥啊?咋那麼快就沒內存了呢?小魚遠程鏈接上服務器,將其中的圖片拖到本地查看,不看不知道,一看嚇一跳,全是各位「老師」的照片啊!啥波多野結衣、蒼井空...應有盡有,全是高清無碼大圖!小魚看了老久才晃過神,擦了擦嘴角的哈喇子。這怎麼行,雖然圖片很好看,可是它養分也跟不上啊!必須得限制。javascript

image-conversion

因而小魚決定讓圖片迴歸它應有的畫質,懷着厚重的心情寫下了圖片壓縮工具。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>

複製代碼
相關文章
相關標籤/搜索