SoFunction
Updated on 2025-04-04

vue-cropper component realizes image cutting and upload

This article shares the specific code for the vue-cropper component to realize image cutting and upload, for your reference, the specific content is as follows

In the past few days, I have been free and used vue and spring boot to practice uploading avatars. So I wrote it down and hope that future development will be helpful.

Introduction of vue-cropper in vue

1. Introduced within the component

import { VueCropper }  from 'vue-cropper' 
components: {
  VueCropper,
},

2. Global introduction

Configure the following code

import VueCropper from 'vue-cropper' 

(VueCropper)

3. Use examples

vue file

<template>
  <el-dialog
    title="Edit avatar"
    :="dialogFormVisible"
    :close-on-click-modal="false"
    append-to-body
  >
    <label class="btn" for="uploads">Select a picture</label>
    <input
      type="file"
      
      :value="imgFile"
      style="position:absolute; clip:rect(0 0 0 0);"
      accept="image/png, image/jpeg, image/gif, image/jpg"
      @change="uploadImg($event, 1)"
    >
    <div style="margin-left:20px;">
      <div class="show-preview" :style="{'overflow': 'hidden', 'margin': '5px'}">
        <div :style="" class="preview" style="width: 40px;height: 40px;">
          <img :src="" :style="">
        </div>
      </div>
    </div>
    <div class="cut">
      <vueCropper
        ref="cropper"
        :img=""
        :outputSize=""
        :outputType=""
        :info="true"
        :full=""
        :canMove=""
        :canMoveBox=""
        :original=""
        :autoCrop=""
        :autoCropWidth=""
        :autoCropHeight=""
        :fixedBox=""
        @realTime="realTime"
        @imgLoad="imgLoad"
      ></vueCropper>
    </div>
    <div slot="footer" class="dialog-footer">
      <el-button @click="dialogFormVisible = false" size="small">Pick remove</el-button>
      <el-button type="primary" @click="finish('blob')" size="small">Confirm Certainly</el-button>
    </div>
  </el-dialog>
</template>

<script>
import { VueCropper } from "vue-cropper";
export default {
  components: {
    VueCropper
  },
  data() {
    return {
      previews: {},
      model: false,
      modelSrc: "",
      fileName: "",
      imgFile: "",
      dialogFormVisible: false,
      option: {
        img: "",
        outputSize: 1, //The quality of the cut image (0.1-1)        full: false, //Output original image scale screenshot props name full        outputType: "png",
        canMove: true,
        original: false,
        canMoveBox: true,
        autoCrop: true,
        autoCropWidth: 40,
        autoCropHeight: 40,
        fixedBox: true
      }
    };
  },
  methods: {
    //Upload the picture (click the upload button)    finish(type) {
      let selft = this;
      let formData = new FormData();
      // Output      if (type === "blob") {
        selft.$(data => {
          let img = (data);
           = true;
           = img;
          ("file", data, );
          selft.$(formData, r => {
            if () {
              selft.$();
            } else {
              selft.$message({
                message: ,
                type: "success"
              });
              selft.$ = ;
               = false;
            }
          });
        });
      } else {
        this.$(data => {});
      }
    },
    //Select local picture    uploadImg(e, num) {
      ("uploadImg");
      var selft = this;
      //Upload the picture      var file = [0];
       = ;
      if (!/\.(gif|jpg|jpeg|png|bmp|GIF|JPG|PNG)$/.test()) {
        alert("The image type must be one of .gif,jpeg,jpg,png,bmp");
        return false;
      }
      var reader = new FileReader();
       = e => {
        let data;
        if (typeof  === "object") {
          // Convert Array Buffer to blob If it is base64, it does not need to          data = (new Blob([]));
        } else {
          data = ;
        }
        if (num === 1) {
           = data;
        } else if (num === 2) {
          selft. = data;
        }
      };
      // Convert to base64      // (file)
      // Convert to blob      (file);
    },
    show() {
       = true;
    },
    // Real-time preview function    realTime(data) {
      ("realTime");
       = data;
    },
    imgLoad(msg) {
      ("imgLoad");
      (msg);
    }
  }
};
</script>

<style lang="less">
@import "./";
</style>

less file

.cut {
    width: 300px;
    height: 300px;
    margin: 0px auto;
}

.hh {
    .el-dialog__header {
        padding: 0px;
        line-height: 2;
        background-color: #f3f3f3;
        height: 31px;
        border-bottom: 1px solid #e5e5e5;
        background: #f3f3f3;
        border-top-left-radius: 5px;
        border-top-right-radius: 5px;
    }
    .el-dialog__title {
        float: left;
        height: 31px;
        color: #4c4c4c;
        font-size: 12px;
        line-height: 31px;
        overflow: hidden;
        margin: 0;
        padding-left: 10px;
        font-weight: bold;
        text-shadow: 0 1px 1px #fff;
    }
    .el-dialog__headerbtn {
        position: absolute;
        top: 8px;
        right: 10px;
        padding: 0;
        background: 0 0;
        border: none;
        outline: 0;
        cursor: pointer;
        font-size: 16px;
    }
}

.btn {
    display: inline-block;
    line-height: 1;
    white-space: nowrap;
    cursor: pointer;
    background: #fff;
    border: 1px solid #c0ccda;
    color: #1f2d3d;
    text-align: center;
    box-sizing: border-box;
    outline: none;
    //margin: 20px 10px 0px 0px;
    padding: 9px 15px;
    font-size: 14px;
    border-radius: 4px;
    color: #fff;
    background-color: #50bfff;
    border-color: #50bfff;
    transition: all 0.2s ease;
    text-decoration: none;
    user-select: none;
}

.show-preview {
    flex: 1;
    -webkit-flex: 1;
    display: flex;
    display: -webkit-flex;
    justify-content: center;
    -webkit-justify-content: center;
    .preview {
        overflow: hidden;
        border-radius: 50%;
        border: 1px solid #cccccc;
        background: #cccccc;
    }
}

Configure axios Content-Type when sending a request

// http request interceptor(
  config => {debugger
    let token = ('token')
    if (token) {
       = token;
    }
    if (config &&  && ('upload') > 0) {
      ['Content-Type'] = 'multipart/form-data'
    }
    return config
  },
  err => {
    return (err)
  }
)

boot controller

@RequestMapping("/upload")
 public ResultData upload(@RequestParam("file") MultipartFile file) {
  return (file);
 }

boot service

@Override
 public ResultData upload(MultipartFile file) {
  if (!()) {
   
   StringBuffer requestURL = ();
   int end = ("/user/upload");
   String basePath = (0, end);
   String savePath = basePath + "/static/img/logo/";
   // Get the file name, including the suffix   String fileName = ();

   String saveDbPath = savePath + fileName;

   //Stored in this path: This path is under the static file in the project directory: (Note: This file may need to be created by yourself)   // The reason for putting it under static is that it stores static file resources, that is, input the local server address through the browser, and can be accessed when adding the file name.   String path = ().getResource("").getPath() + "static/img/logo/";

   // This method is a package for file writing. In the util class, import the package and use it. The method will be given later   try {
    ((), path, fileName);
    // Then create the corresponding entity class, add the following path, and then write it through the database operation method    User user = ();
    (saveDbPath);
    User whereUser = new User();
    (());
    (user, "user", whereUser);
    Map<String, Object> map = new HashMap<>();
    ("msg", "The avatar is modified successfully");
    ("data", user);
    return (map);
   } catch (IOException e) {
    ("Image upload==》" + ());
    ();
    return (());
   } catch (Exception e) {
    ("Picture last time==》" + ());
    ();
    return (());
   }

  } else {
   return ("Uploading image failed");
  }
 }

Finish

The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.