03.04 前端女程序媛,手把手教你,如何編寫一個前端圖片的各種效果

前端女程序媛,手把手教你,如何編寫一個前端圖片的各種效果

前言

今天我們要講解下如何編寫一個圖片壓縮、方向糾正插件,附帶著會講解下如何上傳和預覽。

為什麼重點放在圖片壓縮和方向糾正?

相信大家在做項目過程中,經常會遇到上傳圖片到後端,但是由於圖片過大,需要對圖片壓縮處理。特別在移動端,手機拍的照片普遍過於大了,我們有時候只是需要上傳一張頭像,很小就夠用了。還有在部分手機上(已知蘋果手機)拍的照片存在方向角度問題,這時就需要我們來糾正圖片角度了。

很多同學多數時候是在用別人寫好的圖片壓縮上傳插件。針對我們的需求,這些插件有時候不能達到我們最理想的效果,自己寫呢,又不會寫,很是頭疼。今天就深入剖析講解下,教會大家編寫自己的圖片壓縮、方向糾正插件,以及預覽和上傳壓縮後圖片數據。


實現原理

壓縮圖片並且上傳主要用到filereader、canvas 以及 formdata 這三個h5的api和插件EXIF.js。邏輯並不難。整個過程就是:

(1)用戶使用input file上傳圖片的時候,用filereader讀取用戶上傳的圖片數據(base64格式)

(2)把圖片數據傳入img對象,然後將img繪製到canvas上,用EXIF.js對圖片方向進行糾正,再調用canvas.toDataURL對圖片進行壓縮,獲取到壓縮後的base64格式圖片數據,轉成二進制

(3)獲取到壓縮後的圖片二進制數據,預覽。

(4)將壓縮後的圖片二進制數據塞入formdata,再通過XmlHttpRequest提交formdata

如此四步,就完成了圖片的壓縮、方向糾正、預覽和上傳。


插件設計思考

考慮到在實際項目中,可能用不同的開發框架(vue.js/JQ/react.js/angular.js/anu.js等),圖片預覽的UI樣式也可能不同,圖片數據上傳方法可能不同。因為圖片壓縮和方向糾正這兩塊的邏輯多變性比較低,我們這裡把圖片壓縮和方向糾正抽離出來,封裝為一個插件庫。


【一】獲取圖片數據

先是獲取圖片數據,也就是監聽input file的change事件,然後獲取到用來壓縮上傳的文件對象files,將files傳到【圖片壓縮、方向糾正插件】中進行處理。

這時候根據每個人的需求,也可以預覽未壓縮的圖片。

前端女程序媛,手把手教你,如何編寫一個前端圖片的各種效果

【二】圖片壓縮、方向糾正插件實現

上面做完圖片數據的獲取後,就可以做process壓縮圖片的方法了。而壓縮圖片也並不是直接把圖片繪製到canvas再調用一下toDataURL就行的。

在IOS中,canvas繪製圖片是有兩個限制的:

首先是圖片的大小,如果圖片的大小超過兩百萬像素,圖片也是無法繪製到canvas上的,調用drawImage的時候不會報錯,但是你用toDataURL獲取圖片數據的時候獲取到的是空的圖片數據。

再者就是canvas的大小有限制,如果canvas的大小大於大概五百萬像素(即寬高乘積)的時候,不僅圖片畫不出來,其他什麼東西也都是畫不出來的。

應對上面兩種限制,我把圖片寬度、高度壓縮控制在1000px以內,這樣圖片最大就不超過兩百萬像素了。在前端開發中,1000px*1000px基本可以滿足絕大部分的需求了。當然了還有更完美的瓦片式繪製的方法,我們這裡就說瓦片式繪製方法了。

如此一來就解決了IOS上的兩種限制了。

除了上面所述的限制,還有兩個坑,一個就是canvas的toDataURL是隻能壓縮jpg的(

這句話的詳細解釋可以看下面的Tip講解

),當用戶上傳的圖片是png的話,就需要轉成jpg,也就是統一用canvas.toDataURL('image/jpeg', 0.5) , 類型統一設成jpeg,而壓縮比就自己控制了。

另一個就是如果是png轉jpg,繪製到canvas上的時候,canvas存在透明區域的話,當轉成jpg的時候透明區域會變成黑色,因為canvas的透明像素默認為rgba(0,0,0,0),所以轉成jpg就變成rgba(0,0,0,1)了,也就是透明背景會變成了黑色。解決辦法就是繪製之前在canvas上鋪一層白色的底色。

在壓縮圖片之前,我們判斷圖片角度,如果圖片角度不正確,還需要用EXIF.js把圖片角度糾正過來。

壓縮完圖片,把base64的圖片數據轉成二進制數據存儲到暫存區中,等待被getBlobList獲取使用。

Tip:canvas的toDataURL是隻能壓縮jpg

這句話我可能說的不清楚,我想表達的意思是這個api無論是jpeg還是png,最後導出的時候,都跟jpeg沒啥差別了。因為png圖片的透明性質在canvas中是無效的,會被canvas添加默認的黑色背景,我在文中講解的時候,用白色背景處理了,所以最後導出的圖片,無論你設置的是png還是jpeg都跟jpeg沒啥區別了,因為無法保持png的透明度性質了

前端女程序媛,手把手教你,如何編寫一個前端圖片的各種效果

【三】獲取壓縮後的圖片二進制數據,預覽圖片

完成圖片壓縮後,就可以獲取壓縮後的圖片二進制數據了,把獲取到的圖片二進制數據存起來;獲取到數據後,可以拿來預覽。

由於實際項目中,每個項目的UI樣式設計可能不一樣,開發者可以根據自己的UI樣式來預覽圖片。

前端女程序媛,手把手教你,如何編寫一個前端圖片的各種效果

【四】提交圖片數據到後臺

new一個formdata對象,將上一步獲取到的 blobFileList 圖片二進制數據 append 到 formdata中,用任意你喜歡的ajax庫進行上傳。當然也可以用原生ajax上傳。

前端女程序媛,手把手教你,如何編寫一個前端圖片的各種效果

前端女程序媛,手把手教你,如何編寫一個前端圖片的各種效果

對想學習前端的小夥伴,小編給你們準備了全套前端電子版書籍,包含了目前大部分前端開發的書

領取方式,先關注小編,然後私信發“前端”,就能獲取全套書籍,你還不心動嗎?心動就趕緊發私信 ,獲取資源

結語

喜歡這篇文章的話,請關注我,我會持續更新技術文章到我的主頁。謝謝支持~

前端女程序媛,手把手教你,如何編寫一個前端圖片的各種效果

前端/互聯網/程序員/編程語言


分享到:


相關文章: