js使用canvas實(shí)現(xiàn)圖片壓縮,上傳服務(wù)器

實(shí)現(xiàn)思路

  1. 使用input獲取本地文件
  2. 使用FileReader把圖片轉(zhuǎn)為base64格式
  3. 使用html5的canvas壓縮圖片(canvas只能處理base64格式的圖片)
  4. 將壓縮后的base64 數(shù)據(jù)放到input中提交
demo
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>壓縮圖片demo</title>
</head>
<body>
    <img id="img" src="">
    <input id="file" type="file" onchange="compress()">
</body>
<script>

// 對(duì)圖片進(jìn)行壓縮
function compress() { 
    let fileObj = document.getElementById('file').files[0] //上傳文件的對(duì)象
    let reader = new FileReader()
    reader.readAsDataURL(fileObj)
    reader.onload = function(e) {
        let image = new Image() //新建一個(gè)img標(biāo)簽(還沒(méi)嵌入DOM節(jié)點(diǎn))
        image.src = e.target.result
        image.onload = function() {
            let canvas = document.createElement('canvas'), 
            context = canvas.getContext('2d'),
            imageWidth = image.width / 2,    //壓縮后圖片的大小
            imageHeight = image.height / 2,
            data = ''

            canvas.width = imageWidth
            canvas.height = imageHeight

            context.drawImage(image, 0, 0, imageWidth, imageHeight)
            data = canvas.toDataURL('image/jpeg')

            //壓縮完成  這里的data就是我們需要壓縮圖片數(shù)據(jù)
            document.getElementById('img').src = data
        }
    }
}
</script>
</html>
等比壓縮判斷
  var MAX_HEIGHT = 1000;
  if (image.height > MAX_HEIGHT && image.height >= image.width) {
            // 寬度等比例縮放 *=
            image.width *= MAX_HEIGHT / image.height;
            image.height = MAX_HEIGHT;
        }
       //考錄到用戶(hù)上傳的有可能是橫屏圖片同樣過(guò)濾下寬度的圖片峭状。
        if (image.width > MAX_HEIGHT && image.width > image.height) {
            // 寬度等比例縮放 *=
            image.height *= MAX_HEIGHT / image.width;
            image.width = MAX_HEIGHT;
        }

如果要寫(xiě)兼容判斷

//第一種方法判斷
if(window.FileReader) {  
    var fr = new FileReader();  
    // add your code here  
} else {  
    alert("Not supported by your browser!");  
}
//第二種方法判斷
if(typeof FileReader==='undefined'){
    alert('您的瀏覽器不支持圖片上傳,請(qǐng)升級(jí)您的瀏覽器');
      return false;
 }
  • 測(cè)試結(jié)果說(shuō)明:Google逼争,F(xiàn)F优床,IE都支持FileReader
  • 但是IE9及以下瀏覽器不支持FileReader

為什么要使用到 image.onload(onload:等待圖片加載完成會(huì)自動(dòng)觸發(fā)的方法),因?yàn)楫?dāng)image的src發(fā)生改變誓焦,瀏覽器就會(huì)跑去加載這個(gè)src里的資源胆敞。這個(gè)操作是異步的,就是說(shuō)杂伟,js不會(huì)傻傻地在原地等待圖片的加載移层,而是繼續(xù)讀代碼,直到圖片加載完成赫粥,觸發(fā)onload事件观话,js才會(huì)回來(lái)執(zhí)行onload里面的內(nèi)容。

FileReader API

FileReader實(shí)例擁有五種個(gè)方法越平,其中三個(gè)是用來(lái)讀取文件频蛔,另一個(gè)是用來(lái)中斷讀取的。需要注意的是喧笔,無(wú)論讀取成功或是失敗帽驯,方法并不會(huì)返回讀取結(jié)果,這一結(jié)果(儲(chǔ)存在result屬性中)要用FileReader處理事件去獲仁檎ⅰ尼变;
abort,中斷讀取
readAsBinaryString,將文件轉(zhuǎn)化為二進(jìn)制碼(可以讀取任何類(lèi)型文件)
readAsDataURL,讀取文件內(nèi)容,結(jié)果用data:url的字符串形式表示
readAsText,將文件讀取為文本
readAsArrayBuffer浆劲,方法將讀取一個(gè)Blob對(duì)象或者File對(duì)象嫌术,并產(chǎn)生一個(gè)ArrayBuffer對(duì)象。ArrayBuffer對(duì)象是一個(gè)固定長(zhǎng)度的二進(jìn)制數(shù)據(jù)緩沖牌借。它們?cè)谔幚砦募梢耘缮嫌脠?chǎng)(如將JPEG轉(zhuǎn)換為PNG)度气。
readAsText:該方法有兩個(gè)參數(shù),其中第二個(gè)參數(shù)是文本的編碼方式膨报,默認(rèn)值為 UTF-8磷籍。這個(gè)方法非常容易理解适荣,將文件以文本方式讀取,讀取的結(jié)果即是這個(gè)文本文件中的內(nèi)容院领。
readAsText(file,encoding)可按指定編碼方式讀取文件弛矛,但讀取文件的單位是字符,故對(duì)于文本文件比然,只要按規(guī)定的編碼方式讀取即可丈氓;而對(duì)于媒體文件(圖片、音頻强法、視頻)万俗,其內(nèi)部組成并不是按字符排列,故采用readAsText讀取饮怯,會(huì)產(chǎn)生亂碼闰歪,因此不是最理想的讀取文件的方式。
readAsBinaryString:該方法將文件讀取為二進(jìn)制字符串硕淑,通常我們將它傳送到后端课竣,后端可以通過(guò)這段字符串存儲(chǔ)文件。
readAsDataURL:這是例子程序中用到的方法置媳,該方法將文件讀取為一段以 data: 開(kāi)頭的字符串,這段字符串的實(shí)質(zhì)就是 Data URL公条,Data URL是一種將小文件直接嵌入文檔的方案拇囊。這里的小文件通常是指圖像與 html 等格式的文件。
控制臺(tái)為當(dāng)前所傳文件的base64編碼表示靶橱。由于媒體文件的src屬性寥袭,可以通過(guò)采用網(wǎng)絡(luò)地址或base64的方式顯示,因此我們可以利用readAsDataURL實(shí)現(xiàn)對(duì)圖片的預(yù)覽(即img src=data,這個(gè)data就是readAsDataURL處理后的結(jié)果关霸,直接可以用來(lái)顯示)传黄。
FileReader 事件
FileReader.onabort,處理abort事件队寇。該事件在讀取操作被中斷時(shí)觸發(fā)膘掰。
FileReader.onerror,處理error事件佳遣。該事件在讀取操作發(fā)生錯(cuò)誤時(shí)觸發(fā)识埋。
FileReader.onload,處理load事件零渐。該事件在讀取操作完成時(shí)觸發(fā)窒舟。
FileReader.onloadstart,處理loadstart事件诵盼。該事件在讀取操作開(kāi)始時(shí)觸發(fā)惠豺。
FileReader.onloadend银还,處理loadend事件。該事件在讀取操作結(jié)束時(shí)(要么成功洁墙,要么失斢挤琛)觸發(fā)。
FileReader.onprogress扫俺,處理progress事件苍苞。該事件在讀取Blob時(shí)觸發(fā)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末狼纬,一起剝皮案震驚了整個(gè)濱河市羹呵,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌疗琉,老刑警劉巖冈欢,帶你破解...
    沈念sama閱讀 211,743評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異盈简,居然都是意外死亡凑耻,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)柠贤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)香浩,“玉大人,你說(shuō)我怎么就攤上這事臼勉×诳裕” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,285評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵宴霸,是天一觀的道長(zhǎng)囱晴。 經(jīng)常有香客問(wèn)我,道長(zhǎng)瓢谢,這世上最難降的妖魔是什么畸写? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,485評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮氓扛,結(jié)果婚禮上枯芬,老公的妹妹穿的比我還像新娘。我一直安慰自己幢尚,他們只是感情好破停,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著尉剩,像睡著了一般真慢。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上理茎,一...
    開(kāi)封第一講書(shū)人閱讀 49,821評(píng)論 1 290
  • 那天黑界,我揣著相機(jī)與錄音管嬉,去河邊找鬼。 笑死朗鸠,一個(gè)胖子當(dāng)著我的面吹牛蚯撩,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播烛占,決...
    沈念sama閱讀 38,960評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼胎挎,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了忆家?” 一聲冷哼從身側(cè)響起犹菇,我...
    開(kāi)封第一講書(shū)人閱讀 37,719評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎芽卿,沒(méi)想到半個(gè)月后揭芍,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,186評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡卸例,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評(píng)論 2 327
  • 正文 我和宋清朗相戀三年称杨,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片筷转。...
    茶點(diǎn)故事閱讀 38,650評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡姑原,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出呜舒,到底是詐尸還是另有隱情页衙,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布阴绢,位于F島的核電站,受9級(jí)特大地震影響艰躺,放射性物質(zhì)發(fā)生泄漏呻袭。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評(píng)論 3 313
  • 文/蒙蒙 一腺兴、第九天 我趴在偏房一處隱蔽的房頂上張望左电。 院中可真熱鬧,春花似錦页响、人聲如沸篓足。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,757評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)栈拖。三九已至,卻和暖如春没陡,著一層夾襖步出監(jiān)牢的瞬間涩哟,已是汗流浹背索赏。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,991評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留贴彼,地道東北人潜腻。 一個(gè)月前我還...
    沈念sama閱讀 46,370評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像器仗,于是被迫代替她去往敵國(guó)和親融涣。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評(píng)論 2 349