uni-app開發(fā)微信小程序之H5壓縮上傳圖片的問題詳解
前言
關(guān)于微信小程序、H5兼容性問題,今天就壓縮以及上傳圖片做一個可實現(xiàn)方法的簡要闡述。
一、為什么要壓縮圖片
在使用uni-app開發(fā)小程序及H5的具體業(yè)務中,我們會遇到需要讓用戶上傳本地圖片的場景,隨著現(xiàn)在的手機像素越來越高,圖片的大小也越來越大,上傳原圖后一方面是難以上傳成功,另一方面是上傳成功后在列表中圖片太大加載時間過長或者加載失敗。若是直接提示用戶 “無法上傳xxM以上的圖片” ,用戶體驗會不好,于是需要我們對用戶上傳的圖片進行壓縮。而不同平臺之間壓縮圖片的方式并不完全兼容,需要提供不同的方法來實現(xiàn)。本文主要記錄了在不同平臺實現(xiàn)圖片壓縮上傳的其中一種可實現(xiàn)方法。
二、圖片壓縮方式
uni-app官方提供了關(guān)于圖片的一系列內(nèi)置API
首先從選擇圖片開始
uni.chooseImage(OBJECT) 從本地相冊選擇圖片或使用相機拍照。
// 該方法兼容小程序、H5 uni.chooseImage({ count:1, sizeType: ['compressed'], success: res => { // success: 成功則返回圖片的本地文件路徑列表 let size = res.tempFiles[0].size // 選擇第一張圖片 console.log('圖片大小', size, `${size/1000}KB`, `${size/1000/1000}MB`) } })
圖片選擇完畢,下面就是不兼容的地方了 ??
1. 微信小程序
小程序壓縮圖片的方式相對比較簡單,不過有一定的局限性,僅對 jpg 格式有效。
uni.compressImage(OBJECT) 壓縮圖片接口,可選壓縮質(zhì)量。
// 該方法兼容app和小程序,不兼容h5,且僅對jpg格式有效 uni.compressImage({ src: src, // 圖片路徑 quality: 10, // 圖片壓縮質(zhì)量,0~100,默認80,僅對jpg有效 success: res => { console.log(res.tempFilePath,'壓縮后的圖片路徑') // 接下來可以在這里處理圖片上傳 } })
實現(xiàn)圖片上傳
uni.getFileSystemManager() 獲取全局唯一的文件管理器
readFile() 讀取文件,可轉(zhuǎn)換編碼格式
// 該方法不兼容h5 uni.getFileSystemManager().readFile({ filePath: path, // 要讀取的文件路徑 encoding: 'base64', // 編碼格式 success: file => { wx_uploadImage({ // 調(diào)用接口實現(xiàn)上傳圖片,使用其他方式也可以 image: `data:image/png;base64,${file.data}` }).then(res => { console.log('上傳圖片成功', res) this.image = res.storage_path // 賦值或者其他操作 }) } })
2. H5
H5需要使用另外的方式來壓縮圖片,這里用到了canvas。
- 分三步 -
1. 使用canvas限制圖片大?。▔嚎s圖片),并轉(zhuǎn)換為"blob路徑";
uni.getImageInfo() 獲取圖片信息???????
uni.getImageInfo({ src, success(res) { console.log('壓縮前', res); let canvasWidth = res.width; // 圖片原始寬度 let canvasHeight = res.height; // 圖片原始高度 console.log('寬度-',canvasWidth,'高度-',canvasHeight); let img = new Image(); img.src = res.path; let canvas = document.createElement('canvas'); let ctx = canvas.getContext('2d'); // 這里根據(jù)要求限制圖片寬高 if (canvasWidth >= 1000) { canvas.width = canvasWidth * .1; } else { canvas.width = canvasWidth; } if (canvasHeight >= 1000) { canvas.height = canvasHeight * .1; } else { canvas.height = canvasHeight; } ctx.drawImage(img, 0, 0, canvas.width, canvas.height); //toBlob()方法創(chuàng)造Blob對象,用以展示canvas上的圖片 canvas.toBlob(function(fileSrc) { let imgSrc = window.URL.createObjectURL(fileSrc); console.log('壓縮后的blob路徑', imgSrc); }); } });
2. 將 "blob路徑" 轉(zhuǎn)換為 "blob文件"(待會轉(zhuǎn)換base64格式圖片需要用到 "blob文件" 的格式)
// 傳入blob路徑,.then()獲取blob文件 httpRequest(src) { let that = this return new Promise((resolve, reject) => { let xhr = new XMLHttpRequest() xhr.open('GET', src, true) xhr.responseType = 'blob' xhr.onload = function (e) { if (this.status == 200) { let myBlob = this.response let files = new window.File( [myBlob], myBlob.type, { type: myBlob.type } ) // myBlob.type 自定義文件名 resolve(files) } else { reject(false) } } xhr.send() }) },
3. 將 "blob文件" 轉(zhuǎn)換為 base64格式的圖片,最后上傳圖片。
const fileReader = new FileReader() fileReader.readAsDataURL(file) // 讀取blob類型的圖像文件(不是blob路徑),讀取成功觸發(fā)onload方法,并得到result(base64格式的圖片) fileReader.onload = (event) => { console.log(fileReader.result,'fileReader.result - base64格式'); if (fileReader.result) { // 調(diào)用wx_uploadImage接口,圖片大小必須是1M以下,否則報錯 wx_uploadImage({ image: fileReader.result }).then(res => { console.log('上傳圖片成功', res) this.image = res.storage_path }) } }
總結(jié)
總結(jié)一下以上邏輯經(jīng)過封裝后的完整代碼:
// 使用條件編譯區(qū)分微信小程序、H5的圖片壓縮上傳方式 // 點擊上傳圖片 chooseImage(){ uni.chooseImage({ count:1, sizeType: ['compressed'], success: res => { let size = res.tempFiles[0].size console.log('圖片大小', size, `${size/1000}KB`, `${size/1000/1000}MB`) let path = this.picture_show = res.tempFilePaths[0] //本地圖片路徑 - path let file = res.tempFiles[0] //本地圖片文件 - file let compressPath = '' console.log(path,'路徑'); console.log(file,'圖片文件'); // 先壓縮,再轉(zhuǎn)換為base64圖片,再上傳 // #ifdef MP-WEIXIN if (size > 1048576) { this.mp_compressImage(path) } else { this.mp_filetobase64(path) } // #endif // #ifdef H5 if (size > 1048576) { this.h5_compressImage(path); } else { this.h5_filetobase64(file) } // #endif } }) }, // 微信小程序 - 圖片壓縮方法 mp_compressImage(src) { let _this = this // 該方法兼容app和小程序,不兼容h5,且僅對jpg格式有效 uni.compressImage({ src: src, // 圖片路徑 quality: 10, // 圖片壓縮質(zhì)量,0~100,默認80,僅對jpg有效 success: res => { console.log(res.tempFilePath,'壓縮后的圖片路徑') // 接下來可以在這里處理圖片上傳 _this.mp_filetobase64(res.tempFilePath) } }) } // 微信小程序 - 'blob路徑'轉(zhuǎn)base64圖片的方法 mp_filetobase64(path) { // 該方法不兼容h5 uni.getFileSystemManager().readFile({ filePath: path, // 要讀取的文件路徑 encoding: 'base64', // 編碼格式 success: file => { wx_uploadImage({ // 調(diào)用接口實現(xiàn)上傳圖片,使用其他方式也可以 image: `data:image/png;base64,${file.data}` }).then(res => { console.log('上傳圖片成功', res) this.image = res.storage_path // 賦值或者其他操作 }) } }) } // h5 - 圖片壓縮方法 h5_compressImage(src) { let _this = this; uni.getImageInfo({ src, success(res) { console.log('壓縮前', res); let canvasWidth = res.width; // 圖片原始寬度 let canvasHeight = res.height; // 圖片原始高度 console.log('寬度-',canvasWidth,'高度-',canvasHeight); let img = new Image(); img.src = res.path; let canvas = document.createElement('canvas'); let ctx = canvas.getContext('2d'); // 這里根據(jù)要求限制圖片寬高 if (canvasWidth >= 1000) { canvas.width = canvasWidth * .1; } else { canvas.width = canvasWidth; } if (canvasHeight >= 1000) { canvas.height = canvasHeight * .1; } else { canvas.height = canvasHeight; } ctx.drawImage(img, 0, 0, canvas.width, canvas.height); //toBlob()方法創(chuàng)造Blob對象,用以展示canvas上的圖片 canvas.toBlob(function(fileSrc) { let imgSrc = window.URL.createObjectURL(fileSrc); console.log('壓縮后的blob路徑', imgSrc); // 調(diào)用httpRequest方法,把bloburl轉(zhuǎn)換成blob文件 _this.httpRequest(imgSrc).then(res => { console.log(res,'成功轉(zhuǎn)換為blob文件'); _this.h5_filetobase64(res); // 調(diào)用方法,把blob文件轉(zhuǎn)換成base64圖片 }) }); } }); } // 傳入blob路徑,.then()獲取blob文件 httpRequest(src) { let that = this return new Promise((resolve, reject) => { let xhr = new XMLHttpRequest() xhr.open('GET', src, true) xhr.responseType = 'blob' xhr.onload = function (e) { if (this.status == 200) { let myBlob = this.response let files = new window.File( [myBlob], myBlob.type, { type: myBlob.type } ) // myBlob.type 自定義文件名 resolve(files) } else { reject(false) } } xhr.send() }) }, // h5 - 'blob文件'轉(zhuǎn)base64圖片的方法 h5_filetobase64(file) { const fileReader = new FileReader() fileReader.readAsDataURL(file) // 讀取blob類型的圖像文件(不是blob路徑),讀取成功觸發(fā)onload方法,并得到result(base64格式的圖片) fileReader.onload = (event) => { console.log(fileReader.result,'fileReader.result - base64格式'); if (fileReader.result) { // 調(diào)用wx_uploadImage接口,圖片大小必須是1M以下,否則報錯 wx_uploadImage({ image: fileReader.result }).then(res => { console.log('上傳圖片成功', res) this.image = res.storage_path }) } } }
到此這篇關(guān)于uni-app開發(fā)微信小程序之H5壓縮上傳圖片的問題詳解的文章就介紹到這了,更多相關(guān)uni-app小程序H5壓縮上傳圖片內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript自定義localStorage監(jiān)聽事件的解決方法
在項目開發(fā)過程中,發(fā)現(xiàn)有很多時候進行l(wèi)ocalStorage.setItem()操作設置本地存儲后,頁面必須刷新才能夠獲取到存儲數(shù)據(jù),為了解決這個問題,就必須要用到自定義localStorage監(jiān)聽事件了,所以本文給大家介紹了自定義localStorage監(jiān)聽事件,需要的朋友可以參考下2024-10-10JavaScript實現(xiàn)的鼠標響應顏色漸變效果完整實例
這篇文章主要介紹了JavaScript實現(xiàn)的鼠標響應顏色漸變效果,涉及javascript面向?qū)ο蠹笆录O(jiān)聽、響應機制相關(guān)操作技巧,需要的朋友可以參考下2017-02-02一文讀懂JS中的var/let/const和暫時性死區(qū)
這篇文章主要為大家詳細介紹了JavaScript中的var、let、const和暫時性死區(qū)的異同,文中的示例代碼講解詳細,感興趣的小伙伴可以了解一下2023-02-02javascript?實現(xiàn)純前端將數(shù)據(jù)導出excel兩種方式
這篇文章主要介紹了javascript?實現(xiàn)純前端將數(shù)據(jù)導出excel兩種方式,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參一下2022-07-07