vuejs開發(fā)組件分享之H5圖片上傳、壓縮及拍照旋轉(zhuǎn)的問(wèn)題處理
一、前言
三年.net開發(fā)轉(zhuǎn)前端已經(jīng)四個(gè)月了,前端主要用webpack+vue,由于后端轉(zhuǎn)過(guò)來(lái)的,前端不夠系統(tǒng),希望分享下開發(fā)心得與園友一起學(xué)習(xí)。
圖片的上傳之前都是用的插件(ajaxupload),或者傳統(tǒng)上傳圖片的方式,各有利弊:插件的問(wèn)題是依賴jq并且會(huì)使系統(tǒng)比較臃腫,還有傳統(tǒng)的web開發(fā)模式 前后端偶爾在一起及對(duì)用戶體驗(yàn)要求低,現(xiàn)在公司采用webpack+vue+restfullApi開發(fā)模式 前后端完全分離,遵從高內(nèi)聚,低偶爾的原則,開發(fā)人員各司其職,一則提升開發(fā)效率(從長(zhǎng)期來(lái)看,短期對(duì)于很多開發(fā)人員需要有個(gè)適應(yīng)的過(guò)程,特別是初中級(jí)的前端處理業(yè)務(wù)邏輯方面的能力比較欠缺),二則提升用戶體驗(yàn)。今天分享下在項(xiàng)目開發(fā)中寫的的圖片上傳 vue組件。
二、處理問(wèn)題
這里用h5做圖片上傳考慮到瀏覽器支持的問(wèn)題,這里考慮的場(chǎng)景是在做webapp的時(shí)候
1.移動(dòng)web圖片上傳還包括拍攝上傳,但是在移動(dòng)端會(huì)出現(xiàn)拍攝的照片會(huì)旋轉(zhuǎn),處理這個(gè)問(wèn)題需要得到圖片旋轉(zhuǎn)的情況,可以用exif.js來(lái)獲取,具體可以參看文檔
2.圖片壓縮
3.旋轉(zhuǎn)
三、代碼
1組件代碼
<template>
<div>
<input type="file" style="display: none;" id="img-upload" multiple accept="image/*" @change="uploadImg($event)"/>
</div>
</template>
<script>
import EXIF from '../../../Resource/Global/Js/exif'
export default{
name:"image-html5-upload",
props:{
imgArr:{
type:Array,
twoWay: true,
default:Array
},
imgNumLimit:{//一次最多可以上傳多少?gòu)堈掌?
type:Number,
default:4
}
},
methods:{
"uploadImg": function(e){
let tag = e.target;
let fileList = tag.files;
let imgNum = fileList.length;
let _this = this;
_this.imgArr = [];//圖片數(shù)據(jù)清零
if(this.imgArr.length + imgNum > this.imgNumLimit){
alert('一次最多上傳'+this.imgNumLimit+'張圖片!');
return;
}
var Orientation;
for(let i=0;i<imgNum;i++){
EXIF.getData(fileList[i], function(){
Orientation = EXIF.getTag(fileList[i], 'Orientation');
});
let reader = new FileReader();
reader.readAsDataURL(fileList[i]);
reader.onload = function(){
var oReader = new FileReader();
oReader.onload = function(e) {
var image = new Image();
image.src = e.target.result;
image.onload = function() {
var expectWidth = this.naturalWidth;
var expectHeight = this.naturalHeight;
if (this.naturalWidth > this.naturalHeight && this.naturalWidth > 800) {
expectWidth = 800;
expectHeight = expectWidth * this.naturalHeight / this.naturalWidth;
} else if (this.naturalHeight > this.naturalWidth && this.naturalHeight > 1200) {
expectHeight = 1200;
expectWidth = expectHeight * this.naturalWidth / this.naturalHeight;
}
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
canvas.width = expectWidth;
canvas.height = expectHeight;
ctx.drawImage(this, 0, 0, expectWidth, expectHeight);
var base64 = null;
//修復(fù)ios上傳圖片的時(shí)候 被旋轉(zhuǎn)的問(wèn)題
if(Orientation != "" && Orientation != 1){
switch(Orientation){
case 6://需要順時(shí)針(向左)90度旋轉(zhuǎn)
_this.rotateImg(this,'left',canvas);
break;
case 8://需要逆時(shí)針(向右)90度旋轉(zhuǎn)
_this.rotateImg(this,'right',canvas);
break;
case 3://需要180度旋轉(zhuǎn)
_this.rotateImg(this,'right',canvas);//轉(zhuǎn)兩次
_this.rotateImg(this,'right',canvas);
break;
}
}
base64 = canvas.toDataURL("image/jpeg", 0.8);
if(fileList[i].size / 1024000 > 1){
_this.imgScale(base64, 4)
}else{
_this.imgArr.push({"src": base64});
}
console.log(JSON.stringify(_this.imgArr));
};
};
oReader.readAsDataURL(fileList[i]);
}
}
},
"imgScale": function(imgUrl,quality){
let img = new Image();
let _this = this;
let canvas = document.createElement('canvas');
let cxt = canvas.getContext('2d');
img.src = imgUrl;
img.onload = function(){
//縮放后圖片的寬高
let width = img.naturalWidth/quality;
let height = img.naturalHeight/quality;
canvas.width = width;
canvas.height = height;
cxt.drawImage(this, 0, 0, width, height);
_this.imgArr.push({"src": canvas.toDataURL('image/jpeg')});
}
},
"rotateImg":function (img, direction,canvas) {//圖片旋轉(zhuǎn)
var min_step = 0;
var max_step = 3;
if (img == null)return;
var height = img.height;
var width = img.width;
var step = 2;
if (step == null) {
step = min_step;
}
if (direction == 'right') {
step++;
step > max_step && (step = min_step);
} else {
step--;
step < min_step && (step = max_step);
}
var degree = step * 90 * Math.PI / 180;
var ctx = canvas.getContext('2d');
switch (step) {
case 0:
canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0);
break;
case 1:
canvas.width = height;
canvas.height = width;
ctx.rotate(degree);
ctx.drawImage(img, 0, -height);
break;
case 2:
canvas.width = width;
canvas.height = height;
ctx.rotate(degree);
ctx.drawImage(img, -width, -height);
break;
case 3:
canvas.width = height;
canvas.height = width;
ctx.rotate(degree);
ctx.drawImage(img, -width, 0);
break;
}
}
}
}
</script>
2.使用方法
<template>
<div>
<div class="album-img-list">
<ul>
<li v-for="img in imgList"><div class="album-bg-img"><img :src='img.src'> </div></li>
</ul>
</div>
<div class="album">
<label for="img-upload">上傳照片</label>
<image-html5-upload :img-arr.sync="imgList"></image-html5-upload>
</div>
</div>
</template>
以上所述是小編給大家介紹的vuejs開發(fā)組件分享之H5圖片上傳、壓縮及拍照旋轉(zhuǎn)的問(wèn)題處理,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
- Vue2.0實(shí)現(xiàn)調(diào)用攝像頭進(jìn)行拍照功能 exif.js實(shí)現(xiàn)圖片上傳功能
- Vue.js 2.0 移動(dòng)端拍照壓縮圖片預(yù)覽及上傳實(shí)例
- vue2實(shí)現(xiàn)移動(dòng)端上傳、預(yù)覽、壓縮圖片解決拍照旋轉(zhuǎn)問(wèn)題
- Vue.js 2.0 移動(dòng)端拍照壓縮圖片上傳預(yù)覽功能
- Vue調(diào)用PC攝像頭實(shí)現(xiàn)拍照功能
- vue調(diào)取電腦攝像頭實(shí)現(xiàn)拍照功能
- vue調(diào)用本地?cái)z像頭實(shí)現(xiàn)拍照功能
- vue實(shí)現(xiàn)pc端拍照上傳功能
相關(guān)文章
vue自定v-model實(shí)現(xiàn)表單數(shù)據(jù)雙向綁定問(wèn)題
vue.js的一大功能便是實(shí)現(xiàn)數(shù)據(jù)的雙向綁定。這篇文章主要介紹了vue自定v-model實(shí)現(xiàn) 表單數(shù)據(jù)雙向綁定的相關(guān)知識(shí),非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-09-09
vue再次進(jìn)入頁(yè)面不會(huì)再次調(diào)用接口請(qǐng)求問(wèn)題
這篇文章主要介紹了vue再次進(jìn)入頁(yè)面不會(huì)再次調(diào)用接口請(qǐng)求問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08
Vue 項(xiàng)目中如何使用fullcalendar 時(shí)間段選擇插件(類似課程表格)
最近完成一個(gè)項(xiàng)目,需要選擇一個(gè)會(huì)議室,但是最好能夠通過(guò)在圖上顯示出該 會(huì)議室在某某時(shí)間段內(nèi)已經(jīng)被預(yù)定了,初看這個(gè)功能感覺很棘手,仔細(xì)分析下實(shí)現(xiàn)起來(lái)還是挺容易的,下面通過(guò)示例代碼講解Vue項(xiàng)目中使用fullcalendar時(shí)間段選擇插件,感興趣的朋友一起看看吧2024-07-07
vue實(shí)現(xiàn)自定義公共組件及提取公共的方法
這篇文章主要介紹了vue實(shí)現(xiàn)自定義公共組件及提取公共的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-05-05
Vue 通過(guò)自定義指令回顧v-內(nèi)置指令(小結(jié))
這篇文章主要介紹了Vue 通過(guò)自定義指令回顧v-內(nèi)置指令(小結(jié)),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-09-09
vue項(xiàng)目刷新當(dāng)前頁(yè)面的三種方式(重載當(dāng)前頁(yè)面數(shù)據(jù))
這篇文章主要介紹了vue項(xiàng)目刷新當(dāng)前頁(yè)面的三種方式(重載當(dāng)前頁(yè)面數(shù)據(jù)),本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-01-01
Vue Spa切換頁(yè)面時(shí)更改標(biāo)題的實(shí)例代碼
本篇文章主要介紹了Vue Spa切換頁(yè)面時(shí)更改標(biāo)題的實(shí)例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-07-07
在Vue3中使用localStorage保存數(shù)據(jù)的流程步驟
在前端開發(fā)中,尤其是利用Vue3構(gòu)建現(xiàn)代Web應(yīng)用時(shí),掌握如何使用本地存儲(chǔ)(localStorage)來(lái)保存數(shù)據(jù)是非常重要的能力,在這篇博客中,我將詳細(xì)介紹如何在Vue3中使用localStorage保存數(shù)據(jù),并提供示例代碼來(lái)幫助理解,需要的朋友可以參考下2024-06-06

