搜尋
首頁web前端H5教程深入研究HTML5實作圖片壓縮上傳功能_html5教學技巧

深入研究HTML5實作圖片壓縮上傳功能_html5教學技巧

Mar 30, 2017 pm 02:39 PM
html5上傳功能圖片壓縮

上篇文章提到行動端上傳圖片,我們知道現在流量還是挺貴的,手機的像素是越來越高,拍個照動不動就是好幾M,傷不起。雖然客戶端可以輕輕鬆鬆實現圖片壓縮再上傳,但是我們的應用還可能在瀏覽器裡面打開,怎麼辦呢,圖片壓縮。受以前PC上的開發思維影響,尼瑪js哪有權限去操作文件,哪有資格壓縮圖片啊,搞不了,你們客戶端去整吧。只能說自己還是有點井底之蛙了。在HTML5的影響下,前端能幹的事情越來越多了,開發的功能逼格也越來越高了,H5萬歲!前端的魅力也在這,過去不可能的並不意味著現在、以後不可能,努力吧,騷年!

js怎麼壓縮圖片? ? ?潛意識裡確實一開始是覺得實現不了,後來翻閱資料,研究了下,發現可行!搞起!

先說說H5以前我們怎麼上傳,一般是藉由外掛程式、flash或乾脆一個檔案form表單,少操不少心。

自從有了H5,老闆再也不擔心我的開發了。

上篇文章提到圖片上傳用到了FileReader,FormData,實際上主要用這兩個我們基本上能實現圖片的預覽和上傳了。 實現圖片壓縮,我們需要藉助canvas,是的,就是canvas!

大致思路是:

1、建立一個圖片和一個canvas

1、建立一個圖片和一個canvas

XML/HTML Code

var image = new Image(),   
canvas = document.createElement("canvas"),   
ctx = canvas.getContext('2d');
複製內容到剪貼簿

2、我們將input中選擇的圖片地址透過FileReader後來賦給新建的圖片對象,然後將圖片對象丟到canvas畫布上。

XML/HTML Code

var file = obj.files[0];   
var reader = new FileReader();//读取客户端上的文件   
reader.onload = function() {   
var url = reader.result;//读取到的文件内容.这个属性只在读取操作完成之后才有效,
并且数据的格式取决于读取操作是由哪个方法发起的.所以必须使用reader.onload,   
image.src=url;//reader读取的文件内容是base64,利用这个url就能实现上传前预览图片   
...   
};   
image.onload = function() {   
var w = image.naturalWidth,   
h = image.naturalHeight;   
canvas.width = w;   
canvas.height = h;   
ctx.drawImage(image, 0, 0, w, h, 0, 0, w, h);   
fileUpload();   
};   
reader.readAsDataURL(file);
複製內容到剪貼簿

這裡要注意的是,canvas圖片畫到畫布上的時候需要確定canvas的尺寸,同時設定好drawImage的參數,具體如下:XML/HTML Code

void ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
複製內容到剪貼簿

<span style="font-family:NSimsun">dx</span>

<span style="font-family:NSimsun">dx<p></p></span>來源影像的左上角在目標canvas上 X 軸的位置。 <span style="font-family:NSimsun">dy</span><span style="font-family:NSimsun">dy<p></p></span>來源影像的左上角在目標canvas上 Y 軸的位置。 <span style="font-family:NSimsun">dWidth</span><span style="font-family:NSimsun">dWidth<p></p></span>在目標canvas上繪製影像的寬度。 允許對繪製的圖像進行縮放。 如果不說明, 繪製時圖片寬度不會縮放。 <span style="font-family:NSimsun">dHeight</span><span style="font-family:NSimsun">dHeight<p></p></span>在目標canvas上繪製影像的高度。 允許對繪製的影像進行縮放。 如果不說明, 在繪製時圖片高度不會縮放。 <span style="font-family:NSimsun">sx</span><span style="font-family:NSimsun">sx<p></p></span>需要繪製到目標上下文中的,來源影像的矩形選擇框的左上角X 座標。 <span style="font-family:NSimsun">sy</span><span style="font-family:NSimsun">sy<p></p></span>需要繪製到目標上下文中的,來源影像的矩形選擇框的左上角Y 座標。 <span style="font-family:NSimsun">sWidth</span><span style="font-family:NSimsun">sWidth<p></p></span>需要繪製到目標上下文中的,來源影像的矩形選擇框的寬度。如果不說明,整個矩形從座標的sx和sy開始,到圖像的右下角結束。 <span style="font-family:NSimsun">sHeight</span><span style="font-family:NSimsun">sHeight<p></p></span>需要繪製到目標上下文中的,來源影像的矩形選擇框的高度。

為了上傳完整的圖片,這裡dx,dy必須設定為0,dWidth和dHeight必須設定為原始圖片的寬度和高度。這就是為什麼我們需要等待image物件下載後才能獲得其原始尺寸,這很關鍵!

3、圖片上傳

XML/HTML Code

function fileUpload() {   
     var data = canvas.toDataURL("image/jpeg", quality);   
     //dataURL 的格式为 &ldquo;data:image/png;base64,****&rdquo;,逗号之前都是一些说明性的文字,
     我们只需要逗号之后的就行了   
    datadata = data.split(&#39;,&#39;)[1];   
    data = window.atob(data);   
    var ia = new Uint8Array(data.length);   
    for (var i = 0; i < data.length; i++) {   
          ia[i] = data.charCodeAt(i);   
    };   
     //canvas.toDataURL 返回的默认格式就是 image/png   
    var blob = new Blob([ia], {   
     type: "image/jpeg"   
    });   
    var fd = new FormData();   
        fd.append(&#39;myFile&#39;, blob);   
    var xhr = new XMLHttpRequest();   
    xhr.addEventListener("load", opts.success, false);   
    xhr.addEventListener("error", opts.error, false);   
    xhr.open("POST", opts.url);   
    xhr.send(fd);   
 }

XML/HTML Code複製內容到貼片

這裡用的關鍵方法是canvas.toDataURL

XML/HTML CodeXML/HTML CodeXML/HTML CodeXML/HTML CodeXML/HTML CodeXML/HTML CodeXML/HTML CodeXML/HTML CodeXML/HTML Code複製內容到剪貼簿
canvas.toDataURL(type, encoderOptions);

官方的说明是The <span style="font-family:NSimsun">HTMLCanvasElement.toDataURL()</span> method returns a data URI containing a representation of the image in the format specified by the <span style="font-family:NSimsun">type</span> parameter (defaults to PNG). The returned image is in a resolution of 96 dpi.实际上就是读取canvas画布上图片的数据。其默认是png格式,如果第一个参数type是image/jpeg的话,第二个参数encoderOptions就可以用来设置图片的压缩质量,经过测试,如果是png格式,100%的宽高经过该方法还有可能使图片变大~~~~适得其反,所以我们可以在canvas.drawImage的时候适当设置sWidth和sHeight,比如同比例缩小1.5倍等,图片质量其实并不太影响查看,尤其对尺寸比较大的图片来说。

上面还有比较陌生的方法atob,其作用是做解码,因为图片格式的base64.

XML/HTML Code复制内容到剪贴板

var encodedData = window.btoa("Hello, world"); // encode a string   
var decodedData = window.atob(encodedData); // decode the string

该方法解码出来可能是一堆乱码,Uint8Array返回的是8进制整型数组。

Blob是存储二进制文件的容器,典型的Blob对象是一个图片或者声音文件,其默认是PNG格式。

XML/HTML Code复制内容到剪贴板

var blob = new Blob([ia], {   
     type: "image/jpeg"   
    });

最后通过ajax将Blob对象发送到server即可。

整个流程大致如上,但是~~~实现以后测试跑来说:“你不是说图片压缩了吗,为什么图片还是上传那么慢!”,哥拿起手机对妹纸演示了一下,明明很快嘛,于是反道“是你手机不行或者网络不好吧,你下载图片看明明变小了,比之前肯定快,你看我秒传”。呵呵,说归说,还是偷偷检查代码,在浏览器中打时间log,对比没压缩之前的,尼玛!!!居然才快了几百毫秒!!折腾了半天,之前的代码也重构了,玩我呢。

细心的大神看了上面的代码估计能猜出问题在哪,没错,获取本地图片长宽尺寸的时候出了问题。

我去,获取本地4M大小的图片尺寸花了3174ms!!,图片越大时间也越久~

JavaScript Code复制内容到剪贴板

image.onload = function() {   
        var w = image.naturalWidth,   
          h = image.naturalHeight;   
        canvas.width = w / 1.5;   
        canvas.height = h / 1.5;   
        ctx.drawImage(image, 0, 0, w, h, 0, 0, w / 1.5, h / 1.5);   
        Upload.fileUpload(type);   
};

浏览器在本地取图片的时候是没法直接像file.size一样获取其长宽的,只能通过FileReader拿到内容后赋值给新建的image对象,新建的image对象下载需要时间!怎么破?不就是获取本地图片的尺寸吗,难道没有别的办法了?

于是想到了之前研究过的快速获取图片长宽的博文,点击进入 ,demo地址:http://jsbin.com/jivugadure/edit?html,js,output,定时去查询图片加载过程中的高度或者宽度,不用等整个图片加载完毕。

测了下,还是不行,因为定时查询这种方法对常规的server返回的图片有作用,这里图片地址是base64,貌似时间还更久了~哭。

小结一下:

1、用HTML5来压缩图片上传是可行的,在移动端我们不用依赖客户端或者插件,目前主流浏览器支持程度已经很高了。

2、压缩图片一方面是想减少用户上传等待的时间,另外也减少用户为此牺牲的流量,从整体时间来看,因为获取图片尺寸导致多一次下载需要耗时,其实压不压缩时间差别并不是特别大。除非大神们找到合适的方法能够直接获取图片的尺寸,麻烦也告知我一声,万分感谢;

3、既然时间成本差不多,但是我们压缩了图片,减少了图片的大小,减少了流量的消耗,存储空间以及下次获取该图片的时间,所以还是值得的。

 补充源代码:

JavaScript Code复制内容到剪贴板

(function($) {   
    $.extend($.fn, {   
        fileUpload: function(opts) {   
            this.each(function() {   
                var $self = $(this);   
                var quality = opts.quality ? opts.quality / 100 : 0.2;   
                var dom = {   
                    "fileToUpload": $self.find(".fileToUpload"),   
                    "thumb": $self.find(".thumb"),   
                    "progress": $self.find(".upload-progress")   
                };   
                var image = new Image(),   
                    canvas = document.createElement("canvas"),   
                    ctx = canvas.getContext(&#39;2d&#39;);   
                var funs = {   
                    setImageUrl: function(url) {   
                        image.src = url;   
                    },   
                    bindEvent: function() {   
                        console.log(dom.fileToUpload)   
                        dom.fileToUpload.on("change", function() {   
                            funs.fileSelect(this);   
                        });   
                    },   
                    fileSelect: function(obj) {   
                        var file = obj.files[0];   
                        var reader = new FileReader();   
                        reader.onload = function() {   
                            var url = reader.result;   
                            funs.setImageUrl(url);   
                            dom.thumb.html(image);   
                        };   
                        image.onload = function() {   
                            var w = image.naturalWidth,   
                                h = image.naturalHeight;   
                            canvas.width = w;   
                            canvas.height = h;   
                            ctx.drawImage(image, 0, 0, w, h, 0, 0, w, h);   
                            funs.fileUpload();   
                        };   
                        reader.readAsDataURL(file);   
                    },   
                    fileUpload: function() {   
                        var data = canvas.toDataURL("image/jpeg", quality);   
                        //dataURL 的格式为 &ldquo;data:image/png;base64,****&rdquo;,
                        逗号之前都是一些说明性的文字,我们只需要逗号之后的就行了   
                        data = data.split(&#39;,&#39;)[1];   
                        data = window.atob(data);   
                        var ia = new Uint8Array(data.length);   
                        for (var i = 0; i < data.length; i++) {   
                            ia[i] = data.charCodeAt(i);   
                        };   
                        //canvas.toDataURL 返回的默认格式就是 image/png   
                        var blob = new Blob([ia], {   
                            type: "image/jpeg"  
                        });   
                        var fd = new FormData();   
                        fd.append(&#39;myFile&#39;, blob);   
                        var xhr = new XMLHttpRequest();   
                        xhr.addEventListener("load", opts.success, false);   
                        xhr.addEventListener("error", opts.error, false);   
                        xhr.open("POST", opts.url);   
                        xhr.send(fd);   
                    }   
                };   
                funs.bindEvent();   
            });   
        }   
    });   
})(Zepto);

调用方式:

JavaScript Code复制内容到剪贴板

$(".fileUpload").fileUpload({   
  "url": "savetofile.php",   
  "file": "myFile",   
  "success":function(evt){   
  console.log(evt.target.responseText)   
 }   
});

以上就是深入研究HTML5实现图片压缩上传功能_html5教程技巧的内容,更多相关内容请关注PHP中文网(www.php.cn)!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
HTML中的H5標籤是什麼?HTML中的H5標籤是什麼?May 09, 2025 am 12:11 AM

HTML中的H5標籤是第五級標題,用於標記較小的標題或子標題。 1)H5標籤幫助細化內容層次,提升可讀性和SEO。 2)結合CSS可定製樣式,增強視覺效果。 3)合理使用H5標籤,避免濫用,確保內容結構邏輯性。

H5代碼:Web結構的初學者指南H5代碼:Web結構的初學者指南May 08, 2025 am 12:15 AM

HTML5構建網站的方法包括:1.使用語義化標籤定義網頁結構,如、、等;2.嵌入多媒體內容,使用和標籤;3.應用表單驗證和本地存儲等高級功能。通過這些步驟,你可以創建一個結構清晰、功能豐富的現代網頁。

H5代碼結構:組織內容以實現可讀性H5代碼結構:組織內容以實現可讀性May 07, 2025 am 12:06 AM

通過合理的H5代碼結構可以讓頁面在眾多內容中脫穎而出。 1)使用語義化標籤如、、等組織內容,使結構清晰。 2)通過CSS佈局如Flexbox或Grid控制頁面在不同設備上的呈現效果。 3)實現響應式設計,確保頁面在不同屏幕尺寸上自適應。

H5與較舊的HTML版本:比較H5與較舊的HTML版本:比較May 06, 2025 am 12:09 AM

HTML5(H5)與舊版本HTML的主要區別包括:1)H5引入了語義化標籤,2)支持多媒體內容,3)提供離線存儲功能。 H5通過新標籤和API增強了網頁的功能和表現力,如和標籤,提高了用戶體驗和SEO效果,但需注意兼容性問題。

H5與HTML5:澄清術語和關係H5與HTML5:澄清術語和關係May 05, 2025 am 12:02 AM

H5和HTML5的區別在於:1)HTML5是網頁標準,定義結構和內容;2)H5是基於HTML5的移動網頁應用,適用於快速開發和營銷。

HTML5特徵:H5的核心HTML5特徵:H5的核心May 04, 2025 am 12:05 AM

HTML5的核心特性包括語義化標籤、多媒體支持、表單增強和離線存儲與本地存儲。 1.語義化標籤如、等提高了代碼可讀性和SEO效果。 2.多媒體支持通過和標籤簡化了嵌入媒體內容的過程。 3.表單增強引入了新的輸入類型和驗證屬性,簡化了表單開發。 4.離線存儲和本地存儲通過ApplicationCache和localStorage等提高了網頁性能和用戶體驗。

H5:探索最新版本的HTMLH5:探索最新版本的HTMLMay 03, 2025 am 12:14 AM

html5isamajorrevisionofthehtmlStandardThatRevolutionsWebDevelopmentBybyIntroDucingNewSemanticeLementSemelementsandAndCapabilities.1)itenhancesCodereAdabilityAndSeowitability andSeowithelientsLike,and.2)

超越基礎:H5代碼中的高級技術超越基礎:H5代碼中的高級技術May 02, 2025 am 12:03 AM

H5的高級技巧包括:1.利用進行複雜圖形繪製,2.使用WebWorkers提升性能,3.通過WebStorage增強用戶體驗,4.實現響應式設計,5.利用WebRTC實現實時通信,6.進行性能優化和最佳實踐。這些技巧幫助開發者構建更動態、互動和高效的Web應用。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

將Eclipse與SAP NetWeaver應用伺服器整合。

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具