uniapp H5圖片壓縮上傳


場景:

上傳的時候要求圖片的大小在2MB一下,所以要壓縮圖片,App端當時使用的是uni.compressImage(OBJECT)壓縮的,H5端需要手寫

方法一:

1 <template>
 2     <view class="content">
 3         <view @tap="ChooseImage()">點擊上傳圖片</view>
 4     </view>
 5 </template>
 6 
 7 <script>
 8     export default {
 9         data() {
10             return {
11                 title: 'Hello'
12             }
13         },
14         onLoad() {
15 
16         },
17         methods: {
18             ChooseImage() {
19                 uni.chooseImage({
20                     count: 1,
21                     sizeType: ['original', 'compressed'], //可以指定是原圖還是壓縮圖,默認二者都有
22                     sourceType: ['album'], //從相冊選擇
23                     success: res => {
24                         const imgSize = res.tempFiles[0] && res.tempFiles[0].size ? res.tempFiles[0].size : 0;
25                         const imgName = res.tempFiles[0]&&res.tempFiles[0].name?res.tempFiles[0].name:'';
26                         console.log(imgSize)
27                         this.photoCompress(res.tempFiles[0], (base64Codes) => {
28                             var fl = this.dataURLtoFile(base64Codes,imgName)
29                             console.log(fl, "壓縮后的文件")
30                         })
31                     }
32                 })
33             },
34             photoCompress(file, objDiv) {
35                 var ready = new FileReader();
36                 ready.readAsDataURL(file);
37                 const _this = this;
38                 ready.onload = function() {
39                     var fileResult = this.result;
40                     _this.canvasDataURL(fileResult, objDiv)
41                 }
42             },
43             canvasDataURL(path, callback) {
44                 var img = new Image();
45                 img.src = path;
46                 var objCompressed = {}
47                 img.onload = function() {
48                     var that = this;
49                     //默認壓縮后圖片規格
50                     var quality = 0.7;
51                     var w = that.width;
52                     var h = that.height;
53                     var scale = w / h;
54                     //實際要求
55                     w = objCompressed.width || w;
56                     h = objCompressed.height || (w / scale);
57                     //生成canvas
58                     var canvas = document.createElement('canvas');
59                     var ctx = canvas.getContext('2d');
60                     // 創建屬性節點
61                     var anw = document.createAttribute("width");
62                     anw.nodeValue = w;
63                     var anh = document.createAttribute("height");
64                     anh.nodeValue = h;
65                     canvas.setAttributeNode(anw);
66                     canvas.setAttributeNode(anh);
67                     ctx.drawImage(that, 0, 0, w, h);
68 
69                     var base64 = canvas.toDataURL('image/jpeg', quality);
70                     // 回調函數返回base64的值
71                     callback(base64);
72                 }
73             },
74             dataURLtoFile(dataurl,filename) {
75                 var arr = dataurl.split(","),
76                     mime = arr[0].match(/:(.*?);/)[1],
77                     bstr = atob(arr[1]),
78                     n = bstr.length,
79                     u8arr = new Uint8Array(n);
80                 while (n--) {
81                     u8arr[n] = bstr.charCodeAt(n);
82                 }
83                 return new File([u8arr],filename,  { type: mime });
84             }
85         }
86     }
87 </script>
88 
89 <style>
90     
91 </style>
通過壓縮獲取到File的對象,如果直接使用之前上傳圖片的uni.uploadFile(OBJECT)(詳情見: uni.uploadFile(OBJECT) | uni-app官網 (dcloud.io) 會上傳不成功,具體的問題不太清楚好像是file的path的問題,后端的同事不想動他的代碼,只能自己動手了,直接寫原生的ajax上傳
function fileUpload(i) {
            console.log('fileUpload ---->', requestInfo)
            let item = requestInfo.files[i];
            let fileData = {
                fileIndex: i,
                files: requestInfo.files,
                ...item
            };
            var formdata = new FormData();
            formdata.append("file", item);
            var xhr = new XMLHttpRequest();
            xhr.upload.addEventListener("progress", function(e) {
                var percentComplete = Math.round(e.loaded * 100 / e.total);
                requestInfo.onProgressUpdate && requestInfo.onProgressUpdate(Object.assign({},
                    fileData, percentComplete.toString() + '%'));
            });
            xhr.addEventListener("load", function(e) {
                requestInfo.uploadComplete && requestInfo.uploadComplete(Object.assign({}, fileData,
                    xhr.responseText));
            });
            xhr.addEventListener("error", function(e) {
                requestInfo.uploadError && requestInfo.uploadError(Object.assign({}, fileData, e));
            });
            xhr.onreadystatechange = function() {                
                if (xhr.readyState === 4 && xhr.status === 200) {                    
                    requestInfo.onEachUpdate && requestInfo.onEachUpdate({
                        data: xhr.responseText,
                        ...fileData
                    });
                    fileList.push(xhr.responseText);
                    if (len <= i) {
                        resolve(fileList);                    
                    } else {
                        fileUpload(i + 1);
                    }
                } else if (xhr.readyState === 4) {
                    reject('err');
                }
            }
            xhr.open("post", requestInfo.url, true);
            xhr.setRequestHeader('platform', requestInfo.header.platform);
            xhr.setRequestHeader('Access-Token', requestInfo.header['Access-Token']);
            xhr.send(formdata);
        }

問題解決

使用axios上傳也可以

方法二:

1.選擇圖片

uni.chooseImage({
                    count: 6, //默認9
                    // sizeType: ['compressed'], //可以指定是原圖還是壓縮圖,默認二者都有
                    sourceType: ['album'], //從相冊選擇
                    success: function (res) {
                        let tempPaths = res.tempFilePaths
                        if(tempPaths.length + _this.imgList.length > 6) {
                            uni.showToast({
                                title: '上傳圖片最多可選6張',
                                icon: 'none'
                            })
                        } else {
                            _this.imgList = _this.imgList.concat(tempPaths)
                            _this.compressImage()
                        }
                    }
                })

2.

 
            compressImage(){
                for(let i in this.imgList){
                    let imgFile = this.imgList[i]
                    this.getImageInfo(imgFile)
                }
            },

3.獲取圖片信息並壓縮

// 獲取圖片信息
            getImageInfo(src) {
                let _this = this
                uni.getImageInfo({
                    src,
                    success(res) {
                        console.log('壓縮前', res)
                        let canvasWidth = res.width //圖片原始長寬
                        let canvasHeight = res.height
                        let img = new Image()
                        img.src = res.path
                        let canvas = document.createElement('canvas');
                        let ctx = canvas.getContext('2d')
                        canvas.width = canvasWidth / 2
                        canvas.height = canvasHeight / 2
                        ctx.drawImage(img, 0, 0, canvasWidth / 2, canvasHeight / 2)
                        canvas.toBlob(function(fileSrc) {
                            let imgSrc = window.URL.createObjectURL(fileSrc)
                            console.log('壓縮后', imgSrc)
                            _this.uploadFile(imgSrc)
                        })
                    }
                })
            },

4.上傳

// 上傳圖片
            uploadFile(filePath) {
                let _this = this
                uni.uploadFile({
                    url: '/api/api/Profile/UploadImg',
                    name: 'file',
                    filePath,
                    formData: {},
                    success: (res) => {
                        let { data } = JSON.parse(res.data)
                        _this.imgResults.push(data)
                    },
                    fail: (err) => {
                        uni.showToast({
                            title: err.errMsg,
                            icon: 'none'
                        })
                    }
                });
            },

 

來源:https://juejin.cn/post/7044719449252823077


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM