html5 上傳本地圖片處理各類問題

原文仍是在簡書上: html5 上傳本地圖片處理各類問題html

這是最近給公司寫一個項目,項目要求大概是這樣子:
1.上傳手機本地圖片,而後裁剪(後加的需求)
2.可以旋轉圖片,用於裁剪(後面加的需求)
3.填寫各類文字,選擇顏色,以後把文字和2個相關的圖片,水印到裁剪的圖片上,上傳服務器生成一個圖片地址,返回,分享出去。vue

功能就是大概上面這些,其餘的也就是各類小功能,不提了,技術選型說下,總體上使用 Vue(包括 router,resource,webpack等等)html5

那麼這幾個需求怎麼作呢:
一、 本地上傳,使用 html5 的 File Api 拿到圖片的base64編碼,賦值給img的src(坑1,2),而後彈出一個圖層,進行裁剪,最開始裁剪是在img的上面套一個div來進行座標計算,計算完了使用canvas來截取圖片,而後取值(坑3)。
二、這個功能就是使用canvas的旋轉圖片解決,須要注意的是,旋轉的時候要保持橫縱比,並且要注意寬高的大小(坑4)。
三、使用canvas來疊加水印和圖片便可,主要是注意座標。android

那麼說說坑:
一、拿到src的base64編碼,看似沒有問題,實際上有個巨大的問題,不少圖片在手機上顯示爲豎屏,可是拿到的base64編碼,直接賦值給img的src後,發現是橫屏的。最開始發現這種狀況,覺得是個別現象,最後不斷嘗試以後,發現是個很是廣泛的狀況,特別是IPhone手機,並且還分你選擇的圖片文件夾,相冊和照片流同一張圖片,一個橫屏,一個豎屏。致使我徹底不能理解這是爲何???基本一個下午耗在這個問題上了。webpack

直到晚上回去,問我一個朋友IOS開發的大神,@葉孤城__,他告訴我,由於如今IPhone的攝像頭就是橫着的,手機裏顯示豎屏的緣由是ios本身作了處理,他們能夠根據圖片的一個拍攝角度數值來判斷橫豎問題,可是這個數值在咱們web端確拿不到,非常尷尬。那麼怎麼解決這個問題呢?? ------- 我使用的方案:旋轉圖片,可讓用戶本身去主動旋轉圖片,選取角度。 還有另一種解決方案,在坑2也用到,後面講。ios

二、除了這個橫屏以外,android手機有的上傳,選擇了圖片以後,沒有任何反應,我開始一度認爲緣由是不支持html5的File Api,因此沒有顯示出上傳的圖片,後面就各類debugger,發現緣由是沒有觸發Input標籤的change事件,並且無論怎麼樣都沒有辦法觸發,爲了解決這個問題,查閱了各類官方文檔和stackoverflow以後,發現能夠給 type="file"的input添加兩個屬性來表示手機上傳圖片。web

<input type="file" name="image" class="file-choose" id="file" accept="image/*" v-on:change="chooseFileChange($event)" capture/>

這樣添加了 accept 和 capture以後,有問題的android手機,在選擇圖片的時候,有好幾個文件夾,能夠選擇了,其中有的能夠上傳,有的不行,常常仔細的測試發現,sd卡上的圖片是拿不到的,也就不會觸發change事件,由於沒有root權限去拿文件數據。又是一個無解問題,由於你的web在瀏覽器裏面,權限就是低啊,(不得不吐槽下web的權限問題,媽蛋)怎麼解決問題呢??? 繞過去,也就是說若是你的頁面是嵌套在大家公司本身App裏面的,就讓App幫你,那麼咱們項目是微信傳播的,必定在微信瀏覽器裏面,因此能夠調用微信的JSSDK的選擇圖片接口,他是能夠越過這些權限,並且還有一個好處,就是解決坑1的問題,他會處理橫屏問題,就是把看着豎屏,實際橫屏的上傳時都處理爲豎屏,可是代價也不小,你要選擇圖片,拿到一個key,而後繼續調用sdk傳到微信的服務器,拿到一個serverid,這個id傳給本身的服務端,讓他們經過這個id,去微信下載圖片到本身的服務器,返回給你一個Url。過程很曲折,並且下載次數有限制(能夠跟微信申請加載限制);canvas

參考: 微信 js sdk 選擇圖片接口瀏覽器

三、咱們繼續說坑,以上問題,解決了以後,就是裁剪了,開始我使用的方案是這樣子的,獲取到base64以後,賦值給一個img,而後在這個img上進行框選移動,計算座標而後裁剪,pc端徹底沒有任何問題,效率很高,可是放到微信上面測試,發現3個問題(媽蛋,手機端就是坑,一個功能,3個不一樣的問題),第一個問題,你們都知道如今手機像素高,圖片不小,上傳過來以後,base64也不小,放到img的src中其實就是內存中了,致使整個微信特別容易崩潰(就是崩潰,他就崩潰了,微信就崩潰了---三遍),第二個問題,使用vue的on來綁定touch事件,響應很慢,移動一點都不平滑,並且也會崩潰,沒錯,又崩潰了。第三個問題,旋轉要使用canvas轉化,先去圖片數據,轉完後,在給圖片src賦值,很麻煩。服務器

解決方案: 統一使用canvas,不要再用img,知道裁剪完成了,把img的base64拿到就行,並且導出的時候,使用jpeg不要是png,下降一些畫質,我以爲徹底沒有影響,也就是圖片的裁剪,旋轉都是canvas,事件建議直接原生綁定。

四、旋轉的坑,這個的問題是咱們必須保存住原始圖片的數據,進行canvas先旋轉而後drawImage,要不沒有旋轉出來,canvas本身的imageData,貌似沒有辦法旋轉,我試了矩陣的方式好像都不行(也多是本身數學很差!!!若是有人知道,就demo)。

以上就是此次項目,遇到的各類大坑,其餘都是小的地方,不過整體來講,完成了任務,而且使用了新的技術Vue.js。Vue的component仍是很是好用的,注意父子關係,props的繼承就沒問題了。

歡迎你們交流相關技術, 若是對Vue感興趣,能夠加QQ羣: 364912432,240319632。

相關文章
相關標籤/搜索