vue-cropperjs 基本使用 及其裁剪前压缩,相同图片第二次选择失效,第二次压缩失效,第一次图片转Base64 失效 打印‘data:,' 的问题

 cnpm install --save vue-cropperjs

import VueCropper from "vue-cropperjs";

 components: { VueCropper },
          
                          <div class="crop-demo">
                            <img :src="cropImg" class="pre-img" />
                            <div v-show="bendiisshowxiugai[0]" class="crop-demo-btn">
                              {{$t('lang.Click_change_image')}}
                              <input
                                class="crop-input"
                                type="file"
                                name="image"
                                ref="head_picture_file"
                                accept="image/*"
                                id="change"
                                @change="setImage"
                              />
                            </div>
                          </div>

                        <el-dialog
                            :title="$t('lang.Crop_Image')"
                            :visible.sync="dialogVisible"
                            width="30%"
                          >
                            <vue-cropper
                              ref="cropper"
                              :src="imgSrc"
                              :aspect-ratio="cropperAspectWH"
                              :ready="cropImage"
                              :zoom="cropImage"
                              :cropmove="cropImage"
                              style="width:100%;height:300px;"
                            ></vue-cropper>
                            <span slot="footer" class="dialog-footer">
                              <el-button @click="cancelCrop">{{$t('lang.cancel')}}</el-button>
                              <el-button type="primary" @click="upladPic">{{$t('lang.confirm')}}</el-button>
                            </span>
                          </el-dialog>
 //以下五条都是截图插件的  data中的数据
      defaultSrc: require("../../../assets/xxx.png"), //默认图片
      fileList: [],     
      imgSrc: "",    
      cropImg: "",
      dialogVisible: false,
      img_size: "",
      max_fuyuan_defaultSrc: [],
 setImage(e) {
      let that = this;
      let file = e.target.files[0];
      if (!file.type.includes("image/")) {
        return;
      }
      this.reader = "";
      let canvas = "";
      let ctx = "";
      let img = "";
      that.imgSrc = "";
      this.reader = new FileReader();

      this.reader.onload = event => {
        if (file.size >= 1024 * 1024 * 1) {
          console.log("图片过大");
          var quality = 1; //压缩图片的质量
          canvas = document.createElement("canvas"); //创建画布
          ctx = canvas.getContext("2d");
          img = new Image();
          img.src = event.target.result;
          img.onload = function() {
                const width = img.width;
                const height = img.height;
                canvas.width = 800; //这里可以自定义你的图片大小
                canvas.height = 800 * (img.height / img.width);
                console.log(img.width, img.height, canvas.width, canvas.height);    //图片转化时打印'data:,'的原因 就是获取Dom元素img的信息,img onload要比渲染的快,没能拿到宽高。
                                                                                    //所以在下面的that.imgSrc = canvas.toDataURL("image/jpeg", quality);时出现打印'data:,'的情况
            setTimeout(() => {                                                      //我的解决方案就是用计时器来延迟获取宽高以及转化的操作
              ctx.fillRect(0, 0, 0, 0);
              ctx.drawImage(img, 0, 0, 800, canvas.height);
              that.imgSrc = canvas.toDataURL("image/jpeg", quality); //将图片转为Base64 之后预览要用
                that.$refs.cropper &&
                  that.$refs.cropper[0].replace(that.imgSrc);      //第二次压缩失效的原因和解决方法就是这句。。。 that.$refs.cropper[0].replace(that.imgSrc);
                that.dialogVisible = true;
            }, 50);
          };
        } else {
          that.dialogVisible = true;
          that.imgSrc = event.target.result;
          that.$refs.cropper &&
            that.$refs.cropper[0].replace(event.target.result);
        }
      };
      that.reader.readAsDataURL(file);
    },
    cropImage() {
      this.cropImg = this.$refs.cropper[0].getCroppedCanvas().toDataURL();
    },
    cancelCrop() {
      this.dialogVisible = false;
      this.cropImg = this.max_fuyuan_defaultSrc[
        this.max_fuyuan_defaultSrc.length - 1
      ];
      $("#change").val(""); //取消change事件            //第二次选择相同图片的时候change事件没有触发所以不会弹出弹窗,要先清除   就是这句。。。
    },
    upladPic() {
      this.sumitImageFile(this.cropImg);
      this.dialogVisible = false;
    },
    sumitImageFile(base64Codes) {
      $("#change").val(""); //取消change事件
      let that = this;
      var formData = new FormData();
      //convertBase64UrlToBlob函数是将base64编码转换为Blob
      var picName = new Date().getTime() + ".png"; //给截图的文件命名
      formData.append(
        "file",
        that.convertBase64UrlToBlob(base64Codes),
        picName
      ); //append函数的第一个参数是后台获取数据的参数名,和html标签的input的name属性功能相同
      this.max_fuyuan_defaultSrc.push(this.imgSrc);
      if (this.img_size / 1024 / 1024 < 1.5) {
        serviceApi.requestPostUploadFile(formData).then(body => {
          that.defaultSrc = body.file_name;
          // that.cropImg = that.defaultSrc; //截图用的
        });
      } else {
        this.$message({
          message: "要上传图片太大!",
          type: "warning"
        });
        this.max_fuyuan_defaultSrc.pop();
        //  that.imgSrc=that.cropImg=this.max_fuyuan_defaultSrc;





        that.imgSrc = that.cropImg = this.max_fuyuan_defaultSrc[
          this.max_fuyuan_defaultSrc.length - 1
        ];
      }
    },
    //将以base64的图片url数据转换为Blob
    convertBase64UrlToBlob(urlData) {
      var bytes = window.atob(urlData.split(",")[1]); //去掉url的头,并转换为byte
      //处理异常,将ascii码小于0的转换为大于0
      var ab = new ArrayBuffer(bytes.length);
      var ia = new Uint8Array(ab);
      for (var i = 0; i < bytes.length; i++) {
        ia[i] = bytes.charCodeAt(i);
      }
      let size = new Blob([ab], { type: "image/png" });
      this.img_size = size.size;
      return new Blob([ab], { type: "image/png" });
    }

由于时间关系 以上代码并不完全 仅供参考 下次再发叭。。。
另附我找到的相关的好文章
https://segmentfault.com/q/1010000009665100
https://blog.csdn.net/aithena/article/details/103034718
https://www.thinbug.com/q/16077010
https://stackoverflow.com/questions/40908729/html5-canvas-todataurl-returns-data-in-firefox
http://www.360doc.com/content/18/0928/22/13328254_790527851.shtml
https://www.cnblogs.com/goloving/p/8260206.html
http://www.mamicode.com/info-detail-2151760.html
https://www.jianshu.com/p/f9986bd52ec6
https://blog.csdn.net/qq_36538012/article/details/97984553
我遇到的问题 有的有好几种可能的原因 可以参考以上的

首先是用this.cropImg 和this.max_fuyuan_defaultSrc保存 从服务器拿到的最开始的默认图片进行展示和存储,
然后this.max_fuyuan_defaultSrc 用在这数组保存每次在弹窗里截取之后的图片,如果点击取消截取 就返回数组的上一张图片给this.imgSrc在这里显示

弹窗每次点开的时候都进行判断选择的图片是不是大于1M 的 如果是就进行压缩

然后上传给服务器的时候我又判断了一下是不是大于1.5M 中间留了保险的空间哟 如果图片大于1.5M 就又用this.max_fuyuan_defaultSrc进行了回退了

posted @ 2020-05-26 19:52  王二疯  阅读(1233)  评论(0编辑  收藏  举报