vue中上传图片并裁剪

先安装

npm install vue-cropper // npm 安装
yarn add vue-cropper // yarn 安装

 引用

// 全局引用

main.js import VueCropper from 'vue-cropper'

Vue.use(VueCropper) 

上传按钮

<el-upload
         :class="{hide:hideUpload}"
        multiple
        :file-list="imageUrl1"
        :action="action"
        list-type="picture-card"
        :on-preview="handlePictureCardPreview"
        :on-remove="handleRemove"
        :limit="limit"
        :headers="headers"
        :on-success="handleAvatarSuccess"
        :on-exceed="handleExceed"
        :before-remove="beforeRemove"
      >
        <i class="el-icon-plus"></i>
      </el-upload>

 弹出的裁剪框

 

<!-- vueCropper 剪裁图片实现-->
    <el-dialog
      title="图片剪裁"
      :visible.sync="dialogVisible"
      class="crop-dialog"
      append-to-body
    >
      <div class="cropper-content">
        <div class="cropper" style="text-align: center">
          <vueCropper
            ref="cropper"
            :img="option.img"
            :outputSize="option.size"
            :outputType="option.outputType"
            :info="true"
            :full="option.full"
            :canMove="option.canMove"
            :canMoveBox="option.canMoveBox"
            :original="option.original"
            :autoCrop="option.autoCrop"
            :fixed="option.fixed"
            :fixedNumber="option.fixedNumber"
            :centerBox="option.centerBox"
            :infoTrue="option.infoTrue"
            :fixedBox="option.fixedBox"
            :autoCropWidth="option.autoCropWidth"
            :autoCropHeight="option.autoCropHeight"
            @cropMoving="cropMoving"
          />
        </div>
      </div>
      <div class="action-box">
        <!-- <el-upload
          class="upload-demo"
          action=""
          :auto-upload="false"
          :show-file-list="false"
          :on-change="handleAvatarSuccess"
        > -->
        <!-- <el-upload
           :class="{hide:hideUpload}"
          multiple
          :file-list="imageUrl1"
          :action="action"
          :on-preview="handlePictureCardPreview"
          :on-remove="handleRemove"
          :limit="limit"
          :headers="headers"
          :on-success="handleAvatarSuccess"
          :on-exceed="handleExceed"
          :before-remove="beforeRemove"
          :show-file-list="false"
        >
          <el-button type="primary" plain>更换图片</el-button>
        </el-upload> -->
        <!-- <el-button type="primary" plain @click="clearImgHandle">
          清除图片
        </el-button> -->
        <el-button type="primary" plain @click="rotateLeftHandle">
          左旋转
        </el-button>
        <el-button type="primary" plain @click="rotateRightHandle">
          右旋转
        </el-button>
        <el-button type="primary" plain @click="changeScaleHandle(1)">
          放 大
        </el-button>
        <el-button type="primary" plain @click="changeScaleHandle(-1)">
          缩 小
        </el-button>
        <!-- <el-button type="primary" plain @click="downloadHandle('blob')"
          >下载</el-button
        > -->
      </div>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="finish" :loading="loading">
          确 认
        </el-button>
      </div>
    </el-dialog>

 

data(){
    return {
        dialogimgVisible: false,
      action: process.env.VUE_APP_BASE_API + "/ksUser/submitAttachment",
      headers: {},
      imageUrl1: [],
      // 裁剪框
      isPreview: false,
      dialogVisible: false,
      previewImg: "", // 预览图片地址
      // 裁剪组件的基础配置option
      option: {
        img: "", // 裁剪图片的地址
        info: true, // 裁剪框的大小信息
        outputSize: 1, // 裁剪生成图片的质量
        outputType: "png", // 裁剪生成图片的格式
        canScale: true, // 图片是否允许滚轮缩放
        autoCrop: true, // 是否默认生成截图框
        canMoveBox: true, // 截图框能否拖动
        autoCropWidth: 0, // 默认生成截图框宽度
        autoCropHeight: 0, // 默认生成截图框高度
        fixedBox: true, // 固定截图框大小 不允许改变
        fixed: true, // 是否开启截图框宽高固定比例
        fixedNumber: [1, 1], // 截图框的宽高比例
        full: false, // 是否输出原图比例的截图
        original: false, // 上传图片按照原始比例渲染
        centerBox: false, // 截图框是否被限制在图片里面
        infoTrue: true, // true 为展示真实输出图片宽高 false 展示看到的截图框宽高
      },
      // 防止重复提交
      loading: false,
      fileNames: "", //图片的名称
      imgList: [],
    }
}

 

methods: {
    handleRemove(file, fileList) {
      console.log(file, fileList);
    },
    handlePictureCardPreview(file) {
      this.dialogImageUrl = file.url;
      this.dialogimgVisible = true;
    },
    // 上传成功
    handleAvatarSuccess(res, file) {
      // console.log(res, "上传");
      console.log(file, "上传成功文件");
      // console.log(this.imgIndex, "第几个上传");
      this.fileNames = file.response.name;
      this.imageUrl1.push(file.response);
      this.hideUpload = this.imageUrl1.length >= this.limit;

      // 上传成功后将图片地址赋值给裁剪框显示图片
      if (this.option.autoCropWidth != 0) {
        this.$nextTick(async () => {
          // base64方式
          // this.option.img = await fileByBase64(file.raw)
          this.option.img = file.response.url;
          this.loading = false;
          this.dialogVisible = true;
        });
      } else {
        // var imgs = [];
        this.imgList.push(file.response.fileName);
        this.$emit("getUpload", this.imgList);
      }

    },
    // 放大/缩小
    changeScaleHandle(num) {
      num = num || 1;
      this.$refs.cropper.changeScale(num);
    },
    // 左旋转
    rotateLeftHandle() {
      this.$refs.cropper.rotateLeft();
    },
    // 右旋转
    rotateRightHandle() {
      this.$refs.cropper.rotateRight();
    },
    // 下载
    downloadHandle(type) {
      let aLink = document.createElement("a");
      aLink.download = "author-img";
      if (type === "blob") {
        this.$refs.cropper.getCropBlob((data) => {
          let downImg = window.URL.createObjectURL(data);
          aLink.href = window.URL.createObjectURL(data);
          aLink.click();
        });
      } else {
        this.$refs.cropper.getCropData((data) => {
          let downImg = data;
          aLink.href = data;
          aLink.click();
        });
      }
    },
    // 清理图片
    clearImgHandle() {
      this.option.img = "";
    },
    // 截图框移动回调函数
    cropMoving(data) {
      // 截图框的左上角 x,y和右下角坐标x,y
      // let cropAxis = [data.axis.x1, data.axis.y1, data.axis.x2, data.axis.y2]
      // console.log(cropAxis)
    },
    finish() {
      // 获取截图的 blob 数据
      // this.$refs.cropper.getCropBlob((blob) => {
      //   console.log(blob, "blob数据");
      //   this.loading = true;
      //   this.dialogVisible = false;
      //   this.previewImg = URL.createObjectURL(blob);
      //   console.log(this.previewImg, "this.previewImg确认");
      //   this.isPreview = true;
      // });
      // 获取截图的 base64 数据
      this.loading = true;
      this.$refs.cropper.getCropData((data) => {
        // console.log(data, "获取截图的 base64 数据");
        var fileNamed = this.base64ToFile(data, this.fileNames);
        // console.log(fileNamed, "fileNamed图片转换成的filename ");
        let formData = new FormData();
        formData.append("file", fileNamed); //非常重要的一步 这是将base64转换成file传给后端的关键
        // formData.append("flag", "videoImg"); // 额外参数
        submitAttachment(formData).then((res) => {
          if (res.code == 200) {
            this.$message.success("上传成功");
            this.imgList.push(res.fileName);
            this.$emit("getUpload", this.imgList);//将上传完成的图片传给父组件
            this.dialogVisible = false;
          }
        });
      });
    },
    //将base64格式转换为文件格式,因为我这向后台提交数据时需要文件格式
    base64ToFile(urlData, fileName) {
      let arr = urlData.split(",");
      let mime = arr[0].match(/:(.*?);/)[1];
      let bytes = atob(arr[1]); // 解码base64
      let n = bytes.length;
      let ia = new Uint8Array(n);
      while (n--) {
        ia[n] = bytes.charCodeAt(n);
      }
      return new File([ia], fileName, { type: mime });
    },
    // 限制选择
    handleExceed(files, fileList) {
      this.$message.warning(
        `当前限制选择${this.limit}个文件,本次选择了 ${
          files.length
        } 个文件,共选择了 ${files.length + fileList.length} 个文件`
      );
    },
    // 移除
    beforeRemove(file, fileList) {
      this.$confirm(`确定移除该图片?`, "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          const filePath = file.url;
          const i = this.imageUrl1.findIndex((x) => x.url === filePath);
          // 3.调用splice方法,移除图片信息
          this.imageUrl1.splice(i, 1);
          if (this.imgIndex == 1) {
            this.list.householdRegisters.splice(i, 1);
            // this.list.householdRegisters = "";
            this.hideUpload = this.imageUrl1.length >= this.limit;
          }

          if (this.imgIndex == 2) {
            // this.list.idPhotos = "";
            this.list.idPhotos.splice(i, 1);
            this.hideUpload = this.imageUrl1.length >= this.limit;
          }
          if (this.imgIndex == 3) {
            // this.list.diplomas = "";
            this.list.diplomas.splice(i, 1);
            this.hideUpload = this.imageUrl1.length >= this.limit;
          }
          if (this.imgIndex == 4) {
            // this.list.proofOfEmployments = "";
            this.list.proofOfEmployments.splice(i, 1);
            this.hideUpload = this.imageUrl1.length >= this.limit;
          }
          if (this.imgIndex == 5) {
            // this.list.honorCertificates = "";
            this.list.honorCertificates.splice(i, 1);
            this.hideUpload = this.imageUrl1.length >= this.limit;
          }
          if (this.imgIndex == 6) {
            // this.list.videoUploads = "";
            this.list.videoUploads.splice(i, 1);
            this.hideUpload = this.imageUrl1.length >= this.limit;
          }
          this.$message({
            type: "success",
            message: "删除成功!",
          });
        })
        .catch(() => {
          this.$message({
            type: "info",
            message: "已取消删除",
          });
        });
    },
  },

是参照这位博主的改进的  仅作为本人的学习积累笔记  如有侵权 私信我删除谢谢vue+element实现图片上传及裁剪功能(vue-cropper)_努力搬砖的阿一的博客-CSDN博客_element 图片裁切

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue 3提供了许多实用的第三方库来处理图片上传和裁剪,下面我将介绍并展示如何在Vue 3实现这些功能。 首先,我们需要使用一个图片上传的库,比较常用的是`vue-upload-component`。该库提供了一种简单的方式来处理文件上传,并且可以在上传文件时显示进度条。可以通过`npm`或`yarn`来安装该库。 安装完成后,在需要上传图片的组件导入并注册`vue-upload-component`,并在模版使用`<file-upload></file-upload>`标签来创建上传按钮。你还可以设置其他选项,比如允许上传的图片类型、最大文件大小等等。 接下来,我们需要使用一个图片裁剪的库,比较常用的是`vue-cropperjs`。该库通过集成Cropper.js来提供图片裁剪功能。同样地,可以通过`npm`或`yarn`来安装该库。 安装完成后,在需要裁剪图片的组件导入并注册`vue-cropperjs`,并在模版使用`<vue-cropper></vue-cropper>`标签来创建裁剪区域。你可以设置一些属性来定义裁剪区域的大小、裁剪框的宽高比例等等。 接下来,你可以监听图片上传事件,获取到上传的图片文件。然后将该文件传递给`vue-cropperjs`组件,用于裁剪。在裁剪完成后,你可以获取到裁剪后的图片数据,可以根据需要进行保存或展示。 综上所述,使用Vue 3实现图片上传和裁剪非常简单。可以借助第三方库快速完成这些功能。希望以上回答对你有所帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值