前一陣在公司用vue開發(fā)webapp霎俩,遇到一個用戶拍照或者調(diào)用手機相冊展示圖片袭厂,然后上傳服務(wù)器的需求剑刑,接觸前端僅半年的我走上了一路踩坑的道路媳纬,下面我來說說我遇到的那些坑!
各種坑匯總
- 調(diào)取手機相冊
iOS到?jīng)]什么問題施掏,安卓手機好坑啊钮惠,網(wǎng)上搜了很多辦法,要么就是有的手機不管用七芭,要么就是只能調(diào)相冊不能調(diào)相機素挽,要么就是只能調(diào)相機不能調(diào)相冊 - 調(diào)取相冊拿到相片后渲染到界面上,iOS又出了問題狸驳,通過相機拍攝的圖片是旋轉(zhuǎn)過90度的毁菱,或者蘋果里面正常的圖片到了安卓機展示是旋轉(zhuǎn)90的,也有的圖片蘋果上正常在后臺是歪的锌历。身為一個iOS開發(fā)出身的我這就不理解了,經(jīng)過幾番查證峦筒,得出一個結(jié)論究西,蘋果的相機是歪的!
- 圖片渲染過后瀏覽器會崩潰物喷,尤其是在微信卤材,不得不說,微信好坑啊峦失,什么東西到微信上就會出現(xiàn)各種問題扇丛!
- 然后是圖片上傳的問題,一開始采用了文件上傳的形式尉辑,后來結(jié)果測試反饋帆精,很多安卓機不能上傳成功!說多了都是淚隧魄,不多說進正題卓练!
總結(jié)一下我的解決辦法,希望能對跟我一樣還是個小白的人有所幫助
調(diào)取手機相冊和相機
采用h5調(diào)取相冊 雖然是一句話從網(wǎng)頁調(diào)取购啄,但是如果想相冊襟企,相機都調(diào)的話 要這么寫 (我真的是查了好久)
<form id="uploadForm" enctype="multipart/form-data">
<input class="upload-open-photo" accept="image/*" type="file" id="filechooser" v-on:change="btnUploadFile($event)"/>
</form>
圖片渲染
圖片渲染我采用了canvas ,利用了一個叫 exif.js的插件獲取一下手機拍攝的方向(也就是拍照時是豎著拿手機還是橫著狮含,)顽悼,然后判斷下設(shè)備曼振,對iOS設(shè)備的三個方向?qū)D片進行旋轉(zhuǎn),利用canvas畫到畫布上
btnUploadFile(e){
//獲取圖片
var self = this;
var filechooser = document.getElementById('filechooser');
var previewer = document.getElementById('previewer');
var that = e.target;
var files = that.files;
var file = files[0];
//判斷拍攝方向蔚龙,
EXIF.getData(file,function(){
self.orientation=EXIF.getTag(this,'Orientation');
});
self.fileData = file;
// 接受 jpeg, jpg, png 類型的圖片
if (!/\/(?:jpeg|jpg|png)/i.test(file.type)){
return;
}
var reader = new FileReader();
reader.onload = function() {
var result = this.result;
var img = new Image();
//進行圖片的渲染
img.onload = function() {
//圖片旋轉(zhuǎn)壓縮處理后的base64
var compressedDataUrl =self.compress(img,self.fileData.type);
//渲染到img標簽上
self.toPreviewer(compressedDataUrl);
img = null;
};
img.src = result;
};
reader.readAsDataURL(self.fileData);
},
圖片渲染
圖片渲染時不但要把圖片旋轉(zhuǎn)冰评,還要進行壓縮,由于現(xiàn)在相機像素太高府蛇,高清圖片會導(dǎo)致瀏覽器崩潰集索,當然如果是做的微信開發(fā),只需要在微信瀏覽器中適配汇跨,那么可以參考微信jssdk中的調(diào)用相冊的方法务荆,這樣就不會有圖歪和崩潰的問題了。當然如果不是只做微信穷遂,我們還是要進行壓縮函匕,同樣是采用canvas
(http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html )
//對圖片進行旋轉(zhuǎn),壓縮的方法蚪黑,最終返回base64 渲染給img標簽的src
compress(img, fileType) {
var degree=0,drawWidth,drawHeight,width,height;
drawWidth=img.width;
drawHeight=img.height;
//以下改變一下圖片大小
var maxSide = Math.max(drawWidth, drawHeight);
if (maxSide > 1024) {
var minSide = Math.min(drawWidth, drawHeight);
minSide = minSide / maxSide * 1024;
maxSide = 1024;
if (drawWidth > drawHeight) {
drawWidth = maxSide;
drawHeight = minSide;
} else {
drawWidth = minSide;
drawHeight = maxSide;
}
}
var canvas=document.createElement('canvas');
canvas.width=width=drawWidth;
canvas.height=height=drawHeight;
var context=canvas.getContext('2d');
//判斷圖片方向盅惜,重置canvas大小,確定旋轉(zhuǎn)角度忌穿,iphone默認的是home鍵在右方的橫屏拍攝方式
if($.device.ios){
switch(this.orientation){
//iphone橫屏拍攝抒寂,此時home鍵在左側(cè)
case 3:
degree=180;
drawWidth=-width;
drawHeight=-height;
break;
//iphone豎屏拍攝按厘,此時home鍵在下方(正常拿手機的方向)
case 6:
canvas.width=height;
canvas.height=width;
degree=90;
drawWidth=width;
drawHeight=-height;
break;
//iphone豎屏拍攝氓侧,此時home鍵在上方
case 8:
canvas.width=height;
canvas.height=width;
degree=270;
drawWidth=-width;
drawHeight=height;
break;
}
}
//使用canvas旋轉(zhuǎn)校正
context.rotate(degree*Math.PI/180);
context.drawImage(img,0,0,drawWidth,drawHeight);
// 壓縮0.5就是壓縮百分之50
var base64data = canvas.toDataURL(fileType, 0.5);
canvas = context = null;
this.urlbase = base64data;
return base64data;
},
最終拿到base64渲染給img標簽的src
toPreviewer(dataUrl) {
previewer.src = dataUrl;
},
圖片上傳
上面拿到了base64 后臺提供一個base64上傳圖片的接口序宦,base64有個好處是我們獲取到的base64 是進行旋轉(zhuǎn)壓縮后圖片的base64玷犹,這樣我們上傳服務(wù)器穗慕,或從別的地方展示這個圖片都是旋轉(zhuǎn)壓縮后的勺良,如果其他頁面要展示這張圖片铅檩,就省去了旋轉(zhuǎn)壓縮的過程守呜!其實我現(xiàn)在也不知道為什么通過傳文件方式傳圖片有的安卓機不行眠寿,不過改base64上傳方式成功后就業(yè)沒在糾結(jié)躬翁。
感覺踩了不少坑,歸根結(jié)底還是自己前端經(jīng)驗不足岸⒐啊盒发!