您现在的位置是:网站首页>前端技术>uniappuniapp

uniapp h5实现上传图片并压缩处理

神夜2020-04-06 10:24:52uniapp5523人已围观文章来源:神夜个人博客

简介uniapp h5实现图片上传压缩处理

一、compress.js
// #ifdef H5
import wx from 'jweixin-module'
// #endif
//公从号选择图片转换为base64
function wxGetLocalImgData(localId, callback) {
    wx.getLocalImgData({
        localId: localId,
        // 图片的localID
        success: res = >{
            let name = localId.substr(23, localId.length);
            var localData = res.localData;
            if (localData.indexOf('data:image') != 0) {
                localData = 'data:image/jpeg;base64,' + localData;
            }
            localData = localData.replace(/\r|\n/g, '').replace('data:image/jgp', 'data:image/jpeg');
            let base64 = localData.toString().split(',')[1];
            base64ToBlob({
                b64data: base64,
                name: name + '.jpg',
                contentType: 'image/jpg'
            }).then(blob = >{
                callback(blob);
            });
        }
    })
}

//BlobUrl转blob数据  
function objectURLToBlob(url, callback) {
    var http = new XMLHttpRequest();
    http.open("GET", url, true);
    http.responseType = "blob";
    http.onload = function(e) {
        if (this.status == 200 || this.status === 0) {
            callback(this.response)
        }
    };
    http.send()
}

/**H5图片压缩 返回base64 */
function dealImage(path, file, obj, callback) {
    var img = new Image();
    img.src = path;
    img.onload = function() {
        var that = this;
        let imgMaxWidth = 1024; //图片最大宽
        let imgMaxHeight = 1440; //图片最大高
        let imgw = that.width;
        let imgh = that.height;
        let canvasW = imgw;
        let canvasH = imgh;
        if (imgw > imgh && imgw > imgMaxWidth) {
            canvasW = imgMaxWidth;
            canvasH = parseInt(imgMaxWidth * (imgh / imgw));
        } else if (imgw < imgh && imgh > imgMaxHeight) {
            canvasH = imgMaxHeight;
            canvasW = parseInt(imgMaxHeight * (imgw / imgh));
        } else if (imgw == imgh && imgw > imgMaxWidth) {
            canvasW = imgMaxWidth;
            canvasH = imgMaxWidth;
        }
        //生成canvas
        var canvas = document.createElement('canvas');
        var ctx = canvas.getContext('2d');
        canvas.width = canvasW;
        canvas.height = canvasH;
        let EXIF = require('@/utils/exif-js.js');
        EXIF.getData(file,
        function() {
            let Orientation = EXIF.getTag(this, 'Orientation');
            if (typeof(Orientation) == 'undefined') {
                ctx.drawImage(that, 0, 0, canvasW, canvasH);
            } else {
                let w = canvasW,
                h = canvasH;
                switch (Orientation) {
                case 6:
                    //需要顺时针(向右)90度旋转
                    canvas.height = w;
                    canvas.width = h;
                    ctx.rotate(Math.PI / 180 * 90);
                    ctx.drawImage(that, 0, -h, w, h);
                    break;

                case 8:
                    //需要逆时针(向左)90度旋转                      canvas.height = w;
                    canvas.width = h;
                    ctx.rotate(3 * Math.PI / 2);
                    ctx.drawImage(that, -w, 0, w, h);
                    break;

                case 3:
                    //需要180度旋转 转两次
                    ctx.rotate(Math.PI);
                    ctx.drawImage(that, -w, -h, w, h);
                    break;

                default:
                    ctx.drawImage(that, 0, 0, w, h);
                    break;
                }
            }
            var base64 = canvas.toDataURL('image/jpeg', 0.8);
            callback(base64);
        })
    }
}

/****base64转Blob***/
function base64ToBlob({
    b64data = '',
    name = '',
    contentType = '',
    sliceSize = 512
} = {}) {
    return new Promise((resolve, reject) = >{
        // 使用 atob() 方法将数据解码
        let byteCharacters = atob(b64data);
        let byteArrays = [];
        for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
            let slice = byteCharacters.slice(offset, offset + sliceSize);
            let byteNumbers = [];
            for (let i = 0; i < slice.length; i++) {
                byteNumbers.push(slice.charCodeAt(i));
            }
            // 8 位无符号整数值的类型化数组。内容将初始化为 0。
            // 如果无法分配请求数目的字节,则将引发异常。
            byteArrays.push(new Uint8Array(byteNumbers));
        }
        let result = new Blob(byteArrays, {
            type: contentType
        }) result = Object.assign(result, {
            // 这里一定要处理一下 URL.createObjectURL
            preview: URL.createObjectURL(result),
            name: name
        });
        resolve(result)
    })
}

/** base64转file  * filename图片的名字,dataurl是base64地址  */
function dataURLtoFile(dataurl, filename) {
    var arr = dataurl.split(','),
    mime = arr[0].match(/:(.*?);/)[1],
    bstr = atob(arr[1]),
    n = bstr.length,
    u8arr = new Uint8Array(n);
    while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
    }
    return new File([u8arr], filename, {
        type: mime
    });
}

//h5上传图片处理 uptype 1单张 2多张, res图片资源, callback返回函数
function h5uploadDo(uptype, url, callback) {
    var that = this;
    if (uptype == 1) {
        uni.showLoading({
            title: '图片上传中...'
        });
    }
    if (uptype == 2) {
        uni.showLoading({
            title: '图片压缩中...'
        });
    }
    let i = url.lastIndexOf('/');
    let name = url.substr(i + 1, url.length);
    objectURLToBlob(url,
    function(blob) {
        let file = new window.File([blob], name + '.jpg', {
            type: 'jpg'
        });
        let reader = new FileReader();
        reader.readAsDataURL(file);
        reader.onload = function(e) {
            dealImage(this.result, file, {
                width: 1440
            },
            function(base) {
                let b64data = base.toString().split(',')[1];
                base64ToBlob({
                    b64data: b64data,
                    name: name + '.jpg',
                    contentType: 'image/jpg'
                }).then(blob = >{
                    uni.hideLoading();
                    callback(blob);
                });
            });
        };
    });
}

//随机生成字符串
function randomString(len) {  len = len || 32;  
    var $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';
    /****默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1****/
      
    var maxPos = $chars.length;  
    var pwd = '';  
    for (var i = 0; i < len; i++) {    pwd += $chars.charAt(Math.floor(Math.random() * maxPos));  
    }  
    return pwd;
}

//获取图片信息高宽和路径
const getImageInfo = async(path) = >{
    let imgInfo = await uni.getImageInfo({
        src: path
    });
    let imgMaxWidth = 1024; //图片最大宽
    let imgMaxHeight = 1440; //图片最大高
    let imgw = imgInfo[1].width;
    let imgh = imgInfo[1].height;
    let canvasW = imgw;
    let canvasH = imgh;
    if (imgw > imgh && imgw > imgMaxWidth) {
        canvasW = imgMaxWidth;
        canvasH = parseInt(imgMaxWidth * (imgh / imgw));
    } else if (imgw < imgh && imgh > imgMaxHeight) {
        canvasH = imgMaxHeight;
        canvasW = parseInt(imgMaxHeight * (imgw / imgh));
    } else if (imgw == imgh && imgw > imgMaxWidth) {
        canvasW = imgMaxWidth;
        canvasH = imgMaxWidth;
    }
    if (imgw > imgMaxWidth || imgh > imgMaxHeight) {
        uni.showLoading({
            title: '压缩中',
            mask: true
        });
    }
    let name = randomString(32);
    let params = {
        path: imgInfo[1].path,
        name: name + '.jpg',
        imgw: imgw,
        imgh: imgh,
        canvasW: canvasW,
        canvasH: canvasH
    };
    return params;
}

//小程序开始压缩图片
function xcxCompress(imginfo, callback) {
    const ctx = uni.createCanvasContext('attendCanvasId');
    ctx.drawImage(imginfo.path, 0, 0, imginfo.canvasW, imginfo.canvasH);
    ctx.draw(false,
    function() {
        setTimeout(() = >{
            uni.canvasToTempFilePath({
                canvasId: 'attendCanvasId',
                fileType: "jpg",
                success(res) {
                    uni.compressImage({
                        src: res.tempFilePath,
                        quality: 80,
                        success(e) {
                            callback(e.tempFilePath);
                            uni.hideLoading();
                        },
                        fail() {
                            uni.showToast({
                                title: '压缩失败,请重试',
                                icon: 'none'
                            });
                            uni.hideLoading();
                        }
                    })
                },
                fail(res) {
                    uni.showToast({
                        title: '图片缩放失败,请重试',
                        icon: 'none'
                    });
                    uni.hideLoading()
                }
            });
        },
        100);
    });
}

module.exports = {
    // #ifdef H5
    wxGetLocalImgData: wxGetLocalImgData,
    h5uploadDo: h5uploadDo,
    // #endif
    // #ifdef MP-WEIXIN
    getImageInfo: getImageInfo,
    xcxCompress: xcxCompress,
    // #endif
}

二、在vue文件调用

<canvas canvas-id='attendCanvasId' class='myCanvas' :style="'background:#000;margin:30rpx auto; position:absolute; right:1440px; top: -1440px; width:'+canvasWidth+'px; height:'+canvasHeight+'px'"></canvas>


choose_img_avaurl() {
    var that = this
    // #ifdef MP-WEIXIN			
    uni.chooseImage({
        count: 1,
        sizeType: ['compressed'],
        success(res) {
            that.xcxCompress(res.tempFiles, 'avaurl')
        }
    })
    // #endif
    // #ifdef H5
    that.h5wxUploadImg('avaurl');
    // #endif
},

//H5上传图片之普通浏览器和公众号 uptype 1 单张 2多张
h5wxUploadImg(type) {
    if (util.isWeiXin()) {
        this.wxUploadImg(type)
    } else {
        this.h5UploadImg(type);
    }
},

//h5公众号里面上传
wxUploadImg(type) {
    var that = this;
    wx.chooseImage({
        count: 1,
        sizeType: ['compressed'],
        success: function(res) {
            let localIds = res.localIds[0];
            compress.wxGetLocalImgData(localIds,
            function(blob) {
                let url = blob.preview;
                that.h5uploadDo(type, url);
            })
        }
    })
},

//h5普通浏览器上传
h5UploadImg(type) {
    var that = this;
    uni.chooseImage({
        count: 1,
        sizeType: ['compressed'],
        success(res) {
            let url = res.tempFiles[0].path;
            that.h5uploadDo(type, url);
        }
    });
},

//h5上传 type qrCode 二维码 avaurl 头像
h5uploadDo(type, blob) {
    var that = this;
    compress.h5uploadDo(1, blob,
    function(res) {
        if (type == 'qrCode') {
            let arr = [];
            arr.push({
                name: res.name,
                size: 500,
                path: res.preview
            });
            that.app.uploadImg(arr, 'userQrcode',
            function(res2) {
                that.userMsg.wechatQrCodeUrl = res2;
            });
        } else if (type == 'avaurl') {
            let arr = [];
            arr.push({
                name: res.name,
                size: 500,
                path: res.preview
            });
            that.app.uploadImg(arr, 'zbPortrait',
            function(res2) {
                that.userMsg.imgUrl = res2;
            });
        }
    })
},


//小程序canvas压缩图片
async xcxCompress(tempFilePaths) {
    let that = this;
    for (var i = 0; i < tempFilePaths.length; i++) {
        const imginfo = await compress.getImageInfo(tempFilePaths[i].path);
        let arr = [];
        if (imginfo.imgw > 1024 || imginfo.imgh > 1334) {
            that.canvasWidth = imginfo.canvasW;
            that.canvasHeight = imginfo.canvasH;
            compress.xcxCompress(imginfo,
            function(path) {
                that.imgList.push({
                    name: imginfo.name,
                    size: 500,
                    path: path
                });
            });
        } else {
            that.imgList.push({
                name: imginfo.name,
                size: 500,
                path: imginfo.path
            });
        }
    }
},


三、app.vue里面编写上传方法


async uploadImg(arr, type, cb) {
    var that = this const json = await api.apiArray.getOssPolicy({
        noLoading: true,
        method: 'POST',
        query: {
            id: this.globalData.userMsg.userId,
            fileType: type,
            originalFileInfoArr: JSON.stringify(arr)
        }
    }) if (json.data.returnCode != 0) {
        uni.hideLoading()
    }
    var AuthMsg = json.data.result
    var fileName = arr[0].name
    var fileType = fileName.substr(fileName.lastIndexOf('.'), fileName.length) let uploadRes = await uni.uploadFile({
        url: AuthMsg.host,
        filePath: arr[0].path,
        name: 'file',
        formData: {
            name: fileName,
            key: AuthMsg.dir + AuthMsg.uploadNameList[0] + fileType,
            policy: AuthMsg.policy,
            OSSAccessKeyId: AuthMsg.accessKeyId,
            signature: AuthMsg.postSignature,
            success_action_status: "200",
            callback: AuthMsg.callback
        }
    }) if (uploadRes[1].statusCode && uploadRes[1].statusCode == 200) {
        cb(AuthMsg.host + '/' + AuthMsg.dir + AuthMsg.uploadNameList[0] + fileType) return AuthMsg.host + '/' + AuthMsg.dir + AuthMsg.uploadNameList[0] + fileType
    } else {
        return false
    }
}, 


站点信息

  • 建站时间:2017-10-24
  • 网站程序:Hsycms 3.0
  • 文章统计:511条
  • 微信公众号:扫描二维码,关注我们