九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
在瀏覽器端用H5實(shí)現(xiàn)圖片壓縮上傳

多年互聯(lián)網(wǎng)行業(yè)經(jīng)驗(yàn),對(duì)HTML5,node端,前端框架,構(gòu)建工具有濃厚的興趣,目前擔(dān)任專車前端組的技術(shù)負(fù)責(zé)人

一、需求的場(chǎng)景:

在我們的需求中需要有一個(gè)在手機(jī)瀏覽器端,用戶實(shí)現(xiàn)上傳證件照片的功能,我們第一版上了一個(gè)最簡(jiǎn)版,直接讓用戶在本地選擇圖片,然后上傳到公司公共的服務(wù)器上。 功能實(shí)現(xiàn)后我們發(fā)現(xiàn)一個(gè)問(wèn)題,公司公共的服務(wù)器有 2M 圖片的限制,而用戶手機(jī)目前絕大多數(shù)都支持高清拍照,尺寸普遍在 3000 x 2000 的大小;

所以我們采用了在瀏覽器端通過(guò) HTML5 的 fileReader 接口來(lái)處理上傳文件的大小,將重新處理壓縮后的文件在傳給后端,這樣在保證了圖片基本質(zhì)量(由于證件圖片,我們只關(guān)心證件號(hào)碼是否清晰)的情況下,也能夠做到網(wǎng)絡(luò)傳輸內(nèi)容的最小化,讓上傳變得更快,給用戶較好的體驗(yàn)。

二、逐步分析:

首先我們上傳的文件在 input 事件的默認(rèn)參數(shù)里面是一個(gè) file 類型,他是 Binary Large Object 的一個(gè)子集,需要將 Blob 類型轉(zhuǎn)換成 DataUrl,能夠被 HTML5 本地的 Canvas 畫(huà)布解析,通過(guò) Canvas 畫(huà)布根據(jù)一定的壓縮比例重新壓縮后,再將圖片轉(zhuǎn)換成 Blob 傳到公司公共的圖片服務(wù)器上。

  1. select local file -> Blob -> DataUrl -> Canvas compress -> DataUrl -> Blob -> Upload file

三、具體實(shí)現(xiàn)邏輯:

1. 監(jiān)聽(tīng)本地 input 框 change 事件,當(dāng)內(nèi)容變化,從回調(diào)函數(shù)的參數(shù)中拿到 file 文件; 2. 判斷當(dāng)前瀏覽器是否支持本地壓縮(是否支持 HTML5 的 fileReader 方法); 3. 如果不支持本地壓縮,采用傳統(tǒng)方式直接將原始圖片上傳到服務(wù)器上; 4. 如果支持瀏覽器的本地壓縮,那么進(jìn)入到本地壓縮的流程; 5. 壓縮完成后將最新的 blob 類型文件傳遞到公司服務(wù)器上;

  1.       // 用戶在瀏覽器本地選擇上傳圖片

  2.       /*

  3.        * option = {

  4.        *       el: element, // input file element

  5.        *       width: 800,

  6.        *       height: 600,

  7.        *       rate: 1,

  8.        *       cb: callback

  9.        * }

  10.        *

  11.        */

  12.        function compressUploadImageAsClient(option) {

  13.            var opt = {

  14.                el: option.el,

  15.                width: option.width || 800,

  16.                height: option.height || 600,

  17.                rate: option.rate || 1,

  18.                cb: option.cb || function() {},

  19.                postUrl: option.postUrl || '',

  20.                postLoad: option.postLoad || function() {},

  21.                postError: option.postError || function() {},

  22.                postAbort: option.postAbort || function() {}

  23.            };

  24.            opt.el.addEventListener('change', function(e) {

  25.                // 如果不支持H5的filereader方法,直接用原圖上傳

  26.                if(typeof FileReader != 'function') {

  27.                    // sendFile(e.target.files);

  28.                    postFileToServer([e.target.files[0]], opt.postUrl, opt.postLoad, opt.postError, opt.postAbort);

  29.                    return;

  30.                }

  31.                // 將blob類型轉(zhuǎn)換成DataUrl

  32.                readBlobAsDataURL(e.target.files[0], function(url, size) {

  33.                      // 拿到url類型的圖片之后,通過(guò)canvas進(jìn)行壓縮轉(zhuǎn)換

  34.                    readBase64AsBlob({

  35.                        url: url,

  36.                        size: size,

  37.                        width: 800,

  38.                        height: 600,

  39.                        rate: 1,

  40.                        callback: function(dataUrl) {

  41.                            // 在壓縮完成的回調(diào)函數(shù)中得到最新的圖片DataUrl,將其轉(zhuǎn)換成服務(wù)端接口能夠識(shí)別的Blob類型

  42.                            var blob = dataURLtoBlob(dataUrl);

  43.                            // 調(diào)用上傳服務(wù)器圖片的接口

  44.                            postFileToServer([blob], opt.postUrl, opt.postLoad, opt.postError, opt.postAbort);

  45.                        }

  46.                    });

  47.                });

  48.            }, false)

  49.        }

  1.        // file對(duì)象轉(zhuǎn)換成dataurl

  2.        function readBlobAsDataURL(blob, callback) {

  3.            var a = new FileReader();

  4.            a.onload = function(e) {

  5.                callback(e.target.result, blob.size);

  6.            };

  7.            a.readAsDataURL(blob);

  8.        }

  1.        // dataurl轉(zhuǎn)換成blob

  2.        function dataURLtoBlob(dataurl) {

  3.        var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],

  4.            bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);

  5.            while(n--){

  6.                u8arr[n] = bstr.charCodeAt(n);

  7.            }

  8.            return new Blob([u8arr], {type:mime});

  9.        }

  1.        // blob轉(zhuǎn)換成dataUrl,并且通過(guò)canvas畫(huà)布?jí)嚎s重新生成新的dataUrl

  2.        /*

  3.        * option: {

  4.        *     url: image url,

  5.        *     size: image size,

  6.        *     width: 800,

  7.        *     height: 600,

  8.        *     rate: 1,

  9.        *     callback: callback

  10.        * }

  11.        */

  12.        function readBase64AsBlob(option) {

  13.            var opt = {

  14.                url: option.url,

  15.                size: option.size,

  16.                width: option.width || 800,

  17.                height: option.height || 600,

  18.                rate: option.rate || 0.6,

  19.                callback: option.callback || function(url) {}

  20.            };

  21.            var img = new Image();

  22.            img.src = opt.url;

  23.            img.onload = function(){

  24.                var canvas = document.createElement('canvas'), //創(chuàng)建canvas元素

  25.                    width = img.width, //確保canvas的尺寸和圖片一樣

  26.                    height = img.height;

  27.                console.log('壓縮前圖片的尺寸大?。?, width, height);

  28.                // 根據(jù)最大尺寸 800x600的大小,按比例重新設(shè)置圖片的尺寸

  29.                var neww = opt.width;

  30.                var newh = opt.height;

  31.                // 當(dāng)圖片的寬高分別大于800,600的情況下,在對(duì)其進(jìn)行尺寸的壓縮(尺寸壓縮對(duì)最終size的減小有很大作用)

  32.                if(width > opt.width && height > opt.height) {

  33.                    if(height/width > opt.height/opt.width) {

  34.                        newh = opt.height;

  35.                        neww = (opt.height/height) * width;

  36.                    } else {

  37.                        newh = (opt.width/width) * height;

  38.                        neww = opt.width;

  39.                    }

  40.                }

  41.                // 壓縮率

  42.                var rate = opt.rate;

  43.                if(opt.size < 1024*1024*2) {

  44.                    // 小于2m處理;

  45.                    rate = opt.rate * 0.6;

  46.                } else if(opt.size < 1024*1024*4) {

  47.                    // 2m到4m之間

  48.                    rate = opt.rate * 0.4;

  49.                } else if(opt.size < 1024*1024*8) {

  50.                    // 4m到8m之間

  51.                    rate = opt.rate * 0.3;

  52.                } else {

  53.                    // 大于8m的圖片

  54.                    rate = opt.rate * 0.2;

  55.                }

  56.                canvas.width = neww;

  57.                canvas.height = newh;

  58.                canvas.getContext('2d').drawImage(img, 0, 0, neww, newh); //將圖片繪制到canvas中

  59.                var dataURL = canvas.toDataURL('image/jpeg', rate); //轉(zhuǎn)換圖片為dataURL

  60.                opt.callback(dataURL);

  61.            }

  62.        }

  1.        // 通過(guò)ajax上傳圖片到公司服務(wù)器上

  2.        function postFileToServer(files, posturl, success, fail, abort) {

  3.            if (!files || files.length < 1) {

  4.                alert('上傳的文件不能為空');

  5.                return;

  6.            }

  7.            alert('壓縮后的圖片對(duì)象:' files[0].size);

  8.            var formData = new FormData();     // 創(chuàng)建一個(gè)表單對(duì)象FormData

  9.            // formData.append('submit', 'Submit');  // 往表單對(duì)象添加文本字段

  10.             var fileNames = '';

  11.            for (var i = 0; i < files.length; i ) {

  12.                var file = files[i];    // file 對(duì)象有 name, size 屬性

  13.                formData.append( 'file[' i ']', file);       // 往FormData對(duì)象添加File對(duì)象

  14.                fileNames = file.name ' ';

  15.            }

  16.            var xhr = new XMLHttpRequest();

  17.            xhr.addEventListener('load', function(e) {

  18.                success(e);

  19.            }, false);

  20.            xhr.addEventListener('error', function(e) {

  21.                error(e);

  22.            }, false);

  23.            xhr.addEventListener('abort', function(e) {

  24.                abort(e);

  25.            });

  26.            xhr.open('post', posturl, true);

  27.            xhr.send(formData);

  28.        }

 

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)
打開(kāi)APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
了解 JS 壓縮圖片,這一篇就夠了
mui H5+ 調(diào)取 相冊(cè) 拍照 功能 上傳圖片 + 裁剪功能
解決canvas轉(zhuǎn)base64/jpeg時(shí)透明區(qū)域變成黑色背景的方法
移動(dòng)前端
DataURL與File,Blob,canvas對(duì)象之間的互相轉(zhuǎn)換的Javascript
HTML5裁剪圖片并上傳至服務(wù)器實(shí)現(xiàn)原理講解
更多類似文章 >>
生活服務(wù)
熱點(diǎn)新聞
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服