vue-cropper component realizes image cutting and uploading

vue-cropper component realizes image cutting and uploading

This article shares the specific code of the vue-cropper component to implement image cutting and uploading for your reference. The specific content is as follows

These few days, I had some free time and practiced uploading avatars with vue and spring boot, so I wrote it down and hope it will be helpful for future development.

Introduction of vue-cropper in vue

1. Introduction into the component

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

2. Global introduction

Configure the following code in main.js

import VueCropper from 'vue-cropper' 

Vue.use(VueCropper)

3. Usage Examples

vue file

<template>
  <el-dialog
    title="Edit avatar"
    :visible.sync="dialogFormVisible"
    :close-on-click-modal="false"
    append-to-body
  >
    <label class="btn" for="uploads">Select an image</label>
    <input
      type="file"
      id="uploads"
      :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="previews.div" class="preview" style="width: 40px;height: 40px;">
          <img :src="previews.url" :style="previews.img">
        </div>
      </div>
    </div>
    <div class="cut">
      <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"
        :autoCropWidth="option.autoCropWidth"
        :autoCropHeight="option.autoCropHeight"
        :fixedBox="option.fixedBox"
        @realTime="realTime"
        @imgLoad="imgLoad"
      ></vueCropper>
    </div>
    <div slot="footer" class="dialog-footer">
      <el-button @click="dialogFormVisible = false" size="small">Cancel</el-button>
      <el-button type="primary" @click="finish('blob')" size="small">OK</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, //Image quality after cutting (0.1-1)
        full: false, // Output the original image proportion 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();
      // Outputif (type === "blob") {
        selft.$refs.cropper.getCropBlob(data => {
          let img = window.URL.createObjectURL(data);
          selft.model = true;
          selft.modelSrc = img;
          formData.append("file", data, selft.fileName);
          selft.$api.writer.userUpload(formData, r => {
            if (r.code) {
              selft.$alert.error(r.msg);
            } else {
              selft.$message({
                message: r.data.msg,
                type: "success"
              });
              selft.$store.state.userInfo = r.data.data;
              selft.dialogFormVisible = false;
            }
          });
        });
      } else {
        this.$refs.cropper.getCropData(data => {});
      }
    },
    //Select a local image uploadImg(e, num) {
      console.log("uploadImg");
      var selft = this;
      //Upload picture var file = e.target.files[0];
      selft.fileName = file.name;
      if (!/\.(gif|jpg|jpeg|png|bmp|GIF|JPG|PNG)$/.test(e.target.value)) {
        alert("The image type must be one of .gif, jpeg, jpg, png, bmp");
        return false;
      }
      var reader = new FileReader();
      reader.onload = e => {
        let data;
        if (typeof e.target.result === "object") {
          // Convert Array Buffer to blob. If it is base64, it is not needed. data = window.URL.createObjectURL(new Blob([e.target.result]));
        } else {
          data = e.target.result;
        }
        if (num === 1) {
          selft.option.img = data;
        } else if (num === 2) {
          selft.example2.img = data;
        }
      };
      // Convert to base64
      // reader.readAsDataURL(file)
      // Convert to blob
      reader.readAsArrayBuffer(file);
    },
    show() {
      this.dialogFormVisible = true;
    },
    // Real-time preview function realTime(data) {
      console.log("realTime");
      this.previews = data;
    },
    imgLoad(msg) {
      console.log("imgLoad");
      console.log(msg);
    }
  }
};
</script>

<style lang="less">
@import "./userLogo.less";
</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 the Content-Type of axios when sending a request

// http request interceptor axios.interceptors.request.use(
  config => {debugger
    let token = sessionStorage.getItem('token')
    if (token) {
      config.headers.Authorization = token;
    }
    if (config && config.url && config.url.indexOf('upload') > 0) {
      config.headers['Content-Type'] = 'multipart/form-data'
    }
    return config
  },
  err => {
    return Promise.reject(err)
  }
)

Boot controller

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

boot service

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

   String saveDbPath = savePath + fileName;

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

   // This method is a wrapper for writing files. In the util class, import the package to use it. The method will be given later. try {
    FileUtil.fileupload(file.getBytes(), path, fileName);
    // Then create the corresponding entity class, add the following path, and then write User through the database operation method user = sessionUtil.getSessionUser();
    user.setLogo(saveDbPath);
    User whereUser = new User();
    whereUser.setId(user.getId());
    ConfigHelper.update(user, "user", whereUser);
    Map<String, Object> map = new HashMap<>();
    map.put("msg", "Avatar modified successfully");
    map.put("data", user);
    return ResultData.ok(map);
   } catch (IOException e) {
    log.error("Picture upload ==》" + e.getMessage());
    e.printStackTrace();
    return ResultData.failed(e.getMessage());
   } catch (Exception e) {
    log.error("Last picture ==》" + e.getMessage());
    e.printStackTrace();
    return ResultData.failed(e.getMessage());
   }

  } else {
   return ResultData.failed("Upload image failed");
  }
 }

Finish

The above is the full content of this article. I hope it will be helpful for everyone’s study. I also hope that everyone will support 123WORDPRESS.COM.

You may also be interested in:
  • Springboot+Vue-Cropper realizes the effect of avatar cutting and uploading
  • vue-cropper plug-in realizes the encapsulation of image capture and upload component
  • Detailed explanation of how to use vue-cropper, a Vue image cropping plugin
  • Vue-cropper The basic principles and ideas of picture cropping
  • Encapsulating Vue based on cropper.js to realize online image cropping component function
  • Do you know how to use vue-cropper to crop pictures in vue?

<<:  How to run MySQL using docker-compose

>>:  How to install MySQL and MariaDB in Docker

Recommend

VMware virtual machine installation Apple Mac OS super detailed tutorial

Table of contents Summarize Sometimes we need to ...

Detailed tutorial on installing CUDA9.0 on Ubuntu16.04

Preface: This article is based on the experience ...

How are spaces represented in HTML (what do they mean)?

In web development, you often encounter characters...

How to cancel the background color of the a tag when it is clicked in H5

1. Cancel the blue color of the a tag when it is ...

Solve the problem of Nginx returning 404 after configuring proxy_pass

Table of contents 1. Troubleshooting and locating...

JavaScript data transmission between different pages (URL parameter acquisition)

On web pages, we often encounter this situation: ...

Beginners learn some HTML tags (3)

Related articles: Beginners learn some HTML tags ...

Calling the search engine in the page takes Baidu as an example

Today, it suddenly occurred to me that it would be...

Code analysis of synchronous and asynchronous setState issues in React

React originated as an internal project at Facebo...

CentOS 6.5 installation mysql5.7 tutorial

1. New Features MySQL 5.7 is an exciting mileston...

Detailed explanation of MySQL basic operations (Part 2)

Preface This article contains 1. Several major co...