Vue上传图片压缩的问题

Posted jessie-xian

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue上传图片压缩的问题相关的知识,希望对你有一定的参考价值。

上传图片太大,需要前台进行图片压缩
上传图片大于100* 1024 的用canvas 来压缩来解决
然后ios拍照上传会有图片旋转的问题,然后用了github 上的exif.js很好的插件,项目里面npm install exif-js --save 安装,
然后import一下就可以使用了

html

<div class="operate">
    <span class="btn" @click="sendMsg" v-if="isSend&&isCanSend">btndesc</span>
    <span class="btn" v-if="isSend&&!isCanSend">btndesc</span>          
    <label class="choosepic" v-if="!isSend&&!isCanUpload"></label>
    <label class="choosepic" for="uploadcolor" v-if="!isSend&&isCanUpload"></label>
    <input class="fileupload" type="file"  accept="image/*" id="uploadcolor" @change="upload">
</div>

js

    import Exif from 'exif-js'
export default 
  data () 
    return 
      headerImage:'',picValue:''
    
  ,
  mounted () 
  ,
  methods: 
     upload (e) 
          let _this = this;
          console.log('change----------->',e);
           _this.resulting = [];
           let files = e.target.files || e.dataTransfer.files;
           // let length = files.length;
           let timer = setTimeout(()=>
           _this.$loading.show(
                  text: '发送中'
               )
               clearTimeout(timer);
           ,500);
           _this.singleUpload(files[0],0,1);
           _this.isCanUpload = false;
           e.target.value = null;
         ,

        singleUpload(files,i,length)
            this.files = files;
            this.name = this.files.name;
            this.picValue = files;
            this.imgPreview(this.picValue,i,length);
            console.log(this.picValue);
        ,
        imgPreview (file,i,length) 
            let self = this;
            let Orientation;
            // this.$emit('dealupload');

            //去获取拍照时的信息,解决拍出来的照片旋转问题
            EXIF.getData(file, function()
                Orientation = EXIF.getTag(this, 'Orientation');
            );

            // 看支持不支持FileReader
            if (!file || !window.FileReader) 
                self.$loading.hide();
                return;
            

            if (sAser.storage('deviceOS')==2)      //安卓,sAser.storage('deviceOS')==2
                self.checkHash(file,i,length);
            
            else   //ios    sAser.storage('deviceOS')==1
                if (/^image/.test(file.type)) 
                    // 创建一个reader
                    let reader = new FileReader();
                    // 将图片2将转成 base64 格式
                    reader.readAsDataURL(file);
                    // 读取成功后的回调
                    reader.onload = function () 
                        let result = this.result;
                        let img = new Image();
                        img.src = result;
                        img.onload = function () 
                            let data = self.compressImage(img,Orientation,file);
                            self.headerImage = data;
                            let fileCompress = self.convertBase64UrlToBlob(data);
                            self.checkHash(fileCompress,i,length);
                        
                    
                
            
        ,
       rotateImg (img, direction, canvas, lastRotate) 
            //最小与最大旋转方向,图片旋转4次后回到原方向
            const min_step = 0;
            const max_step = 3;
            if (img == null)return;
            //img的高度和宽度不能在img元素隐藏后获取,否则会出错
            let height = 0;
            let width = 0;
            if(lastRotate == true)
                height = canvas.height;
                width = canvas.width;
            else
                height = img.height;
                width = img.width;
            
            let step = 2;
            if (step == null) 
                step = min_step;
            
            if (direction == 'right') 
                step++;
                //旋转到原位置,即超过最大值
                step > max_step && (step = min_step);
             else 
                step--;
                step < min_step && (step = max_step);
            
            //旋转角度以弧度值为参数
            let degree = step * 90 * Math.PI / 180;
            let ctx = canvas.getContext('2d');
            switch (step) 
                case 0:
                    canvas.width = width;
                    canvas.height = height;
                    ctx.drawImage(img, 0, 0, width, height);
                    break;
                case 1:
                    canvas.width = height;
                    canvas.height = width;
                    ctx.rotate(degree);
                    ctx.drawImage(img, 0, -height, width, height);
                    break;
                case 2:
                    canvas.width = width;
                    canvas.height = height;
                    ctx.rotate(degree);
                    ctx.drawImage(img, -width, -height, width, height);
                    break;
                case 3:
                    canvas.width = height;
                    canvas.height = width;
                    ctx.rotate(degree);
                    ctx.drawImage(img, -width, 0, width, height);
                    break;
            
        ,
      //图片压缩
        compressImage(img, Orientation,file) 
            let size = file.size;
            let initSize = img.src.length;
            let maxWidth = 1600;
            let w = img.width;
            let h = img.height;
            console.log('原始 宽度:' + w + ",高度:" + h);

            if(w > maxWidth)
              //如果图片宽度大于1600px,则将图片进行等比缩放
              let hRatio = maxWidth / w;
              w = maxWidth;
              h = h * hRatio;
              console.log('高度缩放比例:' + hRatio +'缩放后 宽度:' + w + ",高度:" + h);
            

            //创建一个image对象,给canvas绘制使用
            let cvs = document.createElement('canvas');
            cvs.width = w;
            cvs.height = h;
            let ctx = cvs.getContext('2d');
            // this.getToast("旋转:" + Orientation, "20em", "22em");
            //修复ios上传图片的时候 被旋转的问题
            if(Orientation != "" && Orientation != 1)
              switch(Orientation)
                case 6://需要顺时针(向左)90度旋转
                  // ctx.rotate(Math.PI / 2);
                  // ctx.drawImage(img, 0, -h, w, h);

                  //上面的方式处理有问题,使用rotateImg方法。其他不能使用rotateImg方法,会有问题
                  this.rotateImg(img,'left',cvs, true);
                  break;
                case 8://需要逆时针(向右)90度旋转
                  ctx.rotate(3 * Math.PI / 2);
                  ctx.drawImage(img, -w, 0, w, h);
                  break;
                case 3://需要180度旋转
                  ctx.rotate(Math.PI);
                  ctx.drawImage(img, -w, -h, w, h);
                  break;
                default:
                  ctx.drawImage(img, 0, 0, w, h);
                  console.log('特殊情況1111111111==========================>',ctx);
                  break;
              
            else
              console.log('特殊情況2222222222222==========================>',ctx);
              ctx.drawImage(img, 0, 0, w, h);
            

            //进行最小压缩
            let rate = 0.3;
            if (size<1048576)
                rate = 1;
            
            console.log('==============fileing===============>',file.size,rate);
            let ndata = cvs.toDataURL('image/jpeg', 0.3);
            console.log('压缩后内容:' + ndata);
            console.log('压缩前:' + initSize);
            console.log('压缩后:' + ndata.length);
            console.log('压缩率:' + ~~(100 * (initSize - ndata.length) / initSize) + "%");
            return ndata;
        ,
        convertBase64UrlToBlob(urlData) 
            //将以base64的图片url数据转换为Blob
            var arr = urlData.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 Blob([u8arr], type: mime);
        ,
        calcHash(file)
            return sha1File(file);
        ,
      
        postImg (file,i,length) 
            //这里写接口
            let _this = this;
            let name = _this.name;
            let data  = ;
            // this.$emit('uploading');
            // let files = this.files;
            let files = file;
            let param = new FormData(); //创建form对象
            if(files!='')
                param.append('file', files,files.name); //单个图片 ,多个用循环 append 添加
            else
                // this.$message.error('请添加图片');
            

            // param.append('param', JSON.stringify(data));//添加form表单中其他数据

            let config = 
                headers:'Content-Type':'multipart/form-data'
            ;  //添加请求头

            this.$http.post(_this.ajaxUrl,param,config)
                .then(response=>
                    //上传成功后,检查上传后的图片是否有效
                    console.log('返回结果',response);
                    _this.uploadState(response,i,length);
                ).catch(err=>
                _this.uploadFail();
                console.log('接口失败返回结果',err);
            )
        ,
        uploadFail()
            //发送图片过程中出现失败的处理
            let _this = this;
            _this.isCanUpload = true;
            _this.$loading.hide();
        ,
  

原文:https://www.cnblogs.com/yf-html/p/9791339.html

以上是关于Vue上传图片压缩的问题的主要内容,如果未能解决你的问题,请参考以下文章

Vue图片压缩上传

Vue图片压缩上传

vue 的图片上传,压缩,exif图片信息识别(手机拍摄横板问题)

快速创建VUE移动端上传图片功能

vue上传图片并压缩后以formData形式传给后台

vue 移动端上传图片结合localResizeIMG插件进行图片压缩