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