js前端實現(xiàn)圖片壓縮上傳的示例代碼
這里有兩張圖片,它們表面看上去是一模一樣的,但實際上各自所占用的內(nèi)存大小相差了180倍。


可以看到右邊的圖片是22.3MB,而左側(cè)的圖片只有127KB,但是實際上這兩張圖片的大小都是22.3MB。
最近在開發(fā)中遇到這樣的一個需求,需要把用戶上傳的圖片先進行一次壓縮,然后再保存到服務(wù)器,這里我們除了優(yōu)先考慮壓縮圖片的大小外,還要顧及圖片壓縮后的清晰度問題。

經(jīng)過對比,圖片并沒有明顯的失真情況,下面給大家分享一下,我的解決方法:
這里我采用element的文件上傳控件來上傳圖片
<el-upload class="avatar-uploader" :action="GLOBAL.serverFileUrl" name="file" drag :show-file-list="false" :on-change="beforeAvatarUpload" > <i class="el-icon-plus avatar-uploader-icon"></i> </el-upload>
定義了三個事件方法
//圖片上傳之前處理事件
beforeAvatarUpload(file) {
console.log(file);
const isJpgPng =
file.raw.type === "image/jpeg" || file.raw.type === "image/png";
if (!isJpgPng ) {
this.GLOBAL.messageEvent("error","上傳頭像圖片只能是 JPG/PNG 格式!");
} else {
this.compressImg(file.raw);
}
return isJpgPng;
},compressImg(file) {
let that = this;
// ?通過FormData構(gòu)造函數(shù)創(chuàng)建一個空對象
let formData = new FormData();
let reader = new FileReader();
// ?將讀取到的文件編碼成DataURL
reader.readAsDataURL(file);
// ?壓縮圖片
reader.onload = function(ev) {
try {
// ?讀取圖片來獲得上傳圖片的寬高
let img = new Image();
img.src = ev.target.result;
img.onload = function(ev) {
// ?將圖片繪制到canvas畫布上進行壓縮
let canvas = document.createElement("canvas");
let context = canvas.getContext("2d");
let imgwidth = img.width;
let imgHeight = img.height;
// ?按比例縮放后圖片寬高;
let targetwidth = imgwidth;
let targetHeight = imgHeight;
// ?/如果原圖寬大于最大寬度
if (targetWidth > targetHeight) {
// ?原圖寬高比例
let scale = targetHeight / 1280;
targetHeight = 1280;
targetWidth' = targetwidth / scale;
} else {
// ?原圖寬高比例
let scale = targetWidth / 1280;
targetWidth = 1280;
targetHeight = targetHeight / scale;
}
// ?縮放后高度仍然大于最大高度繼續(xù)按比例縮小
canvas.width = targetwidth; //canvas的寬=圖片的寬
canvas.height = targetHeight; //canvas的高=圖片的高
context.clearRect(0,0, canvas.width, canvas.height);
context.drawImage(this, 0, 0, canvas.width, canvas.height);
let data = "":
// ?如果圖片小于0.6Mb,不進行壓縮,并返回二進制流
if (file.size <= 628288) {
data = canvas.toDataURL("image/jpeg");
formData.append("file", file);
that.handleChange(file);
}
// ?如果圖片大于e.6Mb,進行壓縮,并返回二進制流
else {
// todo 壓縮文件大小比例
data = canvas.toDataURL("image/jpeg",0.4);
let paper = that.GLOBAL.dataURLtoFile(data, file.name);
formData.append("file", paper);
that.handleChange(paper);
}
};
} catch (error) {
console.log("出現(xiàn)錯誤",error);
}
};
},// todo 調(diào)用上傳接口 文件提交給后臺
handleChange(file) (
let formData = new FormData( );
formData.append("file",file.raw || file);
console.log(formData);
brandServices.uploadFile(formData).then(res => {
if (res.data.errno === 0) {
this.imgUrl = res.data.data;
this.dialogImageUrl = URL.createObjectURL(file);
this.GLOBAL.messageEvent("success",res.data.message);
} else {
this.GLOBAL .messageEvent("error",res .data.message);
}
});
}總結(jié):
先進行圖片上傳前的驗證;接著再對圖片實現(xiàn)壓縮的操作;最后就可以把文件流提交給后臺。
具體的思路是:通過FormData構(gòu)造函數(shù)創(chuàng)建一個空對象,將圖片繪制到canvas畫布上,然后再進行壓縮。用戶上傳的文件超過一定的大小后就可以執(zhí)行壓縮的操作,當(dāng)然如果圖片太小的話,我們就沒必要再壓了。建議采用寬高等比例的方式來壓縮,不然可能會出現(xiàn)圖片變形的情況。
到此這篇關(guān)于js前端實現(xiàn)圖片壓縮上傳的示例代碼的文章就介紹到這了,更多相關(guān)js圖片壓縮上傳內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript將當(dāng)前時間轉(zhuǎn)換成UTC標(biāo)準(zhǔn)時間的方法
這篇文章主要介紹了JavaScript將當(dāng)前時間轉(zhuǎn)換成UTC標(biāo)準(zhǔn)時間的方法,涉及javascript中Date及toUTCString方法的使用技巧,需要的朋友可以參考下2015-04-04
JavaScript實現(xiàn)通過select標(biāo)簽跳轉(zhuǎn)網(wǎng)頁的方法
這篇文章主要介紹了JavaScript實現(xiàn)通過select標(biāo)簽跳轉(zhuǎn)網(wǎng)頁的方法,涉及javascript事件響應(yīng)及窗口操作相關(guān)技巧,需要的朋友可以參考下2016-09-09
JavaScrip實現(xiàn)PHP print_r的數(shù)功能(三種方法)
PHP print_r的函數(shù)很好用,可以用來打印數(shù)組、對象等的結(jié)構(gòu)與數(shù)據(jù),可惜JavaScript并沒有原生提供類似的函數(shù)。不過我們可以試著自己來實現(xiàn)這個函數(shù),下面提供一些方法與思路2013-11-11
Java中int與integer的區(qū)別(基本數(shù)據(jù)類型與引用數(shù)據(jù)類型)
這篇文章主要介紹了int與integer的區(qū)別(基本數(shù)據(jù)類型與引用數(shù)據(jù)類型),簡單的說 int 是基本數(shù)據(jù)類型,integer 是引用數(shù)據(jù)類型,具體區(qū)別詳解大家參考下本文2017-02-02
微信小程序picker組件簡單用法示例【附demo源碼下載】
這篇文章主要介紹了微信小程序picker組件簡單用法,結(jié)合實例形式詳細分析了picker組件的功能、使用方法與相關(guān)注意事項,需要的朋友可以參考下2017-12-12
ES6中Proxy與Reflect實現(xiàn)重載(overload)的方法
這篇文章主要介紹了ES6中Proxy與Reflect實現(xiàn)重載(overload)的方法,分析了重載的原理及使用Proxy和Reflect來實現(xiàn)重載的操作步驟與相關(guān)技巧,需要的朋友可以參考下2017-03-03

