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

實現(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>

// 對圖片進行壓縮
function compress() { 
    let fileObj = document.getElementById('file').files[0] //上傳文件的對象
    let reader = new FileReader()
    reader.readAsDataURL(fileObj)
    reader.onload = function(e) {
        let image = new Image() //新建一個img標(biāo)簽(還沒嵌入DOM節(jié)點)
        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;
        }
       //考錄到用戶上傳的有可能是橫屏圖片同樣過濾下寬度的圖片。
        if (image.width > MAX_HEIGHT && image.width > image.height) {
            // 寬度等比例縮放 *=
            image.height *= MAX_HEIGHT / image.width;
            image.width = MAX_HEIGHT;
        }

如果要寫兼容判斷

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

為什么要使用到 image.onload(onload:等待圖片加載完成會自動觸發(fā)的方法),因為當(dāng)image的src發(fā)生改變,瀏覽器就會跑去加載這個src里的資源。這個操作是異步的,就是說,js不會傻傻地在原地等待圖片的加載,而是繼續(xù)讀代碼,直到圖片加載完成,觸發(fā)onload事件,js才會回來執(zhí)行onload里面的內(nèi)容。

FileReader API

FileReader實例擁有五種個方法,其中三個是用來讀取文件,另一個是用來中斷讀取的。需要注意的是,無論讀取成功或是失敗,方法并不會返回讀取結(jié)果,這一結(jié)果(儲存在result屬性中)要用FileReader處理事件去獲??;
abort,中斷讀取
readAsBinaryString,將文件轉(zhuǎn)化為二進制碼(可以讀取任何類型文件)
readAsDataURL,讀取文件內(nèi)容,結(jié)果用data:url的字符串形式表示
readAsText,將文件讀取為文本
readAsArrayBuffer,方法將讀取一個Blob對象或者File對象,并產(chǎn)生一個ArrayBuffer對象。ArrayBuffer對象是一個固定長度的二進制數(shù)據(jù)緩沖。它們在處理文件可以派上用場(如將JPEG轉(zhuǎn)換為PNG)。
readAsText:該方法有兩個參數(shù),其中第二個參數(shù)是文本的編碼方式,默認值為 UTF-8。這個方法非常容易理解,將文件以文本方式讀取,讀取的結(jié)果即是這個文本文件中的內(nèi)容。
readAsText(file,encoding)可按指定編碼方式讀取文件,但讀取文件的單位是字符,故對于文本文件,只要按規(guī)定的編碼方式讀取即可;而對于媒體文件(圖片、音頻、視頻),其內(nèi)部組成并不是按字符排列,故采用readAsText讀取,會產(chǎn)生亂碼,因此不是最理想的讀取文件的方式。
readAsBinaryString:該方法將文件讀取為二進制字符串,通常我們將它傳送到后端,后端可以通過這段字符串存儲文件。
readAsDataURL:這是例子程序中用到的方法,該方法將文件讀取為一段以 data: 開頭的字符串,這段字符串的實質(zhì)就是 Data URL,Data URL是一種將小文件直接嵌入文檔的方案。這里的小文件通常是指圖像與 html 等格式的文件。
控制臺為當(dāng)前所傳文件的base64編碼表示。由于媒體文件的src屬性,可以通過采用網(wǎng)絡(luò)地址或base64的方式顯示,因此我們可以利用readAsDataURL實現(xiàn)對圖片的預(yù)覽(即img src=data,這個data就是readAsDataURL處理后的結(jié)果,直接可以用來顯示)。
FileReader 事件
FileReader.onabort,處理abort事件。該事件在讀取操作被中斷時觸發(fā)。
FileReader.onerror,處理error事件。該事件在讀取操作發(fā)生錯誤時觸發(fā)。
FileReader.onload,處理load事件。該事件在讀取操作完成時觸發(fā)。
FileReader.onloadstart,處理loadstart事件。該事件在讀取操作開始時觸發(fā)。
FileReader.onloadend,處理loadend事件。該事件在讀取操作結(jié)束時(要么成功,要么失?。┯|發(fā)。
FileReader.onprogress,處理progress事件。該事件在讀取Blob時觸發(fā)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容