Vue使用canvas實現(xiàn)圖片壓縮上傳
本文實例為大家分享了Vue使用canvas實現(xiàn)圖片壓縮上傳的具體代碼,供大家參考,具體內容如下
場景:如用戶頭像等
對于大尺寸圖片的上傳,在前端進行壓縮除了省流量外,最大的意義是極大的提高了用戶體驗。
兩方面:
1、由于上傳圖片尺寸比較小,因此上傳速度會比較快,交互會更加流暢,同時大大降低了網絡異常導致上傳失敗風險。
2、很多網站的圖片上傳功能都會對圖片的大小進行限制,尤其是頭像上傳,限制5M或者2M以內是非常常見的(但是我用單反拍了個頭像,照片超過2M很正常,要對圖片進行處理才能上傳)。如果可以在前端進行壓縮,則理論上對圖片尺寸的限制是沒有必要的。

示例:
主要技術:使用canvas的drawImage()方法。(附:canvas.toDataURL()或者canvas.toBlob())
ctx.drawImage(image, dx, dy); ctx.drawImage(image, dx, dy, dWidth, dHeight); ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
示例:
// html
<input id="file" type="file">
// JS
var eleFile = document.querySelector('#file');
// 壓縮圖片需要的一些元素和對象
var reader = new FileReader(), img = new Image();
// 選擇的文件對象
var file = null;
// 縮放圖片需要的canvas
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
// base64地址圖片加載完畢后
img.onload = function () {
// 圖片原始尺寸
var originWidth = this.width;
var originHeight = this.height;
// 最大尺寸限制
var maxWidth = 400, maxHeight = 400;
// 目標尺寸
var targetWidth = originWidth, targetHeight = originHeight;
// 圖片尺寸超過400x400的限制
if (originWidth > maxWidth || originHeight > maxHeight) {
if (originWidth / originHeight > maxWidth / maxHeight) {
// 更寬,按照寬度限定尺寸
targetWidth = maxWidth;
targetHeight = Math.round(maxWidth * (originHeight / originWidth));
} else {
targetHeight = maxHeight;
targetWidth = Math.round(maxHeight * (originWidth / originHeight));
}
}
// canvas對圖片進行縮放
canvas.width = targetWidth;
canvas.height = targetHeight;
// 清除畫布
context.clearRect(0, 0, targetWidth, targetHeight);
// 圖片壓縮
context.drawImage(img, 0, 0, targetWidth, targetHeight);
// canvas轉為blob并上傳
canvas.toBlob(function (blob) {
// 圖片ajax上傳
var xhr = new XMLHttpRequest();
// 文件上傳成功
xhr.onreadystatechange = function() {
if (xhr.status == 200) {
// xhr.responseText就是返回的數據
}
};
// 開始上傳
xhr.open("POST", 'upload.php', true);
xhr.send(blob);
}, file.type || 'image/png');
};
// 文件base64化,以便獲知圖片原始尺寸
reader.onload = function(e) {
img.src = e.target.result;
};
eleFile.addEventListener('change', function (event) {
file = event.target.files[0];
// 選擇的文件是圖片
if (file.type.indexOf("image") == 0) {
reader.readAsDataURL(file);
}
});
注意:
移動端會出現(xiàn)圖片變形,需要根據設備的dpr對canvas進行放大,再用css進行強制恢復
// 獲取設備dpr
getPixelRatio: function(context) {
let backingStore = context.backingStorePixelRatio ||
context.webkitBackingStorePixelRatio ||
context.mozBackingStorePixelRatio ||
context.msBackingStorePixelRatio ||
context.oBackingStorePixelRatio ||
context.backingStorePixelRatio || 1;
return (window.devicePixelRatio || 1) / backingStore;
}
// 大概這樣
const ctx = this.canvas.getContext("2d");
const dpr = this.getPixelRatio(ctx);
this.$refs.postImg.crossOrigin = "Anonymous";
var oldWidth = this.canvas.width;
var oldHeight = this.canvas.height;
this.canvas.style.width = oldWidth + 'px';
this.canvas.style.height = oldHeight + 'px';
this.canvas.width = oldWidth * dpr;
this.canvas.height = oldHeight * dpr;
ctx.scale(dpr, dpr);
//進行正常的操作
ctx.drawImage(this.$refs.cropImg, 0, 0, 250, 400);
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
Vue聯(lián)動Echarts實現(xiàn)數據大屏展示
這篇文章主要為大家介紹了Vue聯(lián)動Echarts實現(xiàn)數據大屏的展示示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-04-04
vue+webpack實現(xiàn)異步加載三種用法示例詳解
這篇文章主要介紹了vue+webpack實現(xiàn)異步加載的三種用法,文中給大家提到了vue+webpack實現(xiàn)異步組件加載的代碼,非常不錯,具有參考借鑒價值,需要的朋友參考下吧2018-04-04
Vue 列表頁帶參數進詳情頁的操作(router-link)
這篇文章主要介紹了Vue 列表頁帶參數進詳情頁的操作(router-link),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-11-11
sublime如何配置開發(fā)VUE環(huán)境自動格式化代碼
這篇文章主要介紹了sublime如何配置開發(fā)VUE環(huán)境自動格式化代碼問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-03-03
vue.js移動端app之上拉加載以及下拉刷新實戰(zhàn)
這篇文章主要介紹了vue.js移動端app之上拉加載以及下拉刷新實戰(zhàn),非常具有實用價值,需要的朋友可以參考下2017-09-09
vue 實現(xiàn)input表單元素的disabled示例
今天小編就為大家分享一篇vue 實現(xiàn)input表單元素的disabled示例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-10-10

