實現(xiàn)思路
- 使用input獲取本地文件
- 使用FileReader把圖片轉(zhuǎn)為base64格式
- 使用html5的canvas壓縮圖片(canvas只能處理base64格式的圖片)
- 將壓縮后的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ā)。