ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

vue+element 实现图片上传和截取功能

2021-09-18 18:04:17  阅读:220  来源: 互联网

标签:截图 vue data 截取 element let 上传 true image


今天分享一个图片上传和截取功能,需求要求固定尺寸的截取,按照自己的需求进行配置,

实现效果如下:

首先参考element的上传参考地址:Element - The world's most popular Vue UI framework

截取的部分主要用到了vue-cropper

第一步:

安装   npm install vue-cropper

第二步:

1.全局使用 main.js

import VueCropper from 'vue-cropper'
Vue.use(VueCropper)

  2.组件内使用

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

接下来直接上代码:

<template>
  <div>
    <el-upload
      class="heightCredential"
      :action="action"
      :headers="headers"
      :file-list="list"
      :show-file-list="isList"
      :accept="accept"
      :on-success="handleSuccess"
      :before-upload="beforeUpload"
      >
    <div class="uploadBorder flex_jc_center flex_ai_center">
      <img v-if="!isList && list.length" :src="list[0].url" @click.stop=""/>
      <i v-else class="el-icon-plus"></i>
      <slot/>
    </div>
    <i v-show="!isList && list.length" class="el-icon-close img-close" @click.stop="clearFile"></i>
  </el-upload>
    <el-dialog
      append-to-body
      title="广告裁剪"
      ref="dialog"
      width="1200"
      class="img-cropper"
      :visible.sync="dialogVisible"
      :close-on-click-modal="false"
    >
      <div class="cropper-w">
        <div class="cropper" :style="{ width: '100%', height: '360px' }">
          <vueCropper
            ref="cropper"
            :img="option.img"
            :outputSize="option.size"
            :outputType="option.outputType"
            :info="option.info"
            :full="option.full"
            :canMove="option.canMove"
            :canMoveBox="option.canMoveBox"
            :original="option.original"
            :autoCrop="option.autoCrop"
            :autoCropWidth="option.autoCropWidth"
            :autoCropHeight="option.autoCropHeight"
            :fixedBox="option.fixedBox"
          ></vueCropper>
        </div>
      </div>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="finish">确认</el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script>
import axios from 'axios'

export default {
  name: 'BaseCropperUpload',
  props: ["fileList"],
  computed: {
    list() {
      return this.fileList
    }
  },
  data() {
    return {
      action: 上传图片地址,
      dialogVisible:false,
       option: {
        img: "", // 裁剪图片的地址
        info: true, // 裁剪框的大小信息
        outputSize: 0.8, // 裁剪生成图片的质量
        outputType: "jpeg", // 裁剪生成图片的格式
        canScale: false, // 图片是否允许滚轮缩放
        autoCrop: true, // 是否默认生成截图框
        autoCropWidth: 1200, // 默认生成截图框宽度
        autoCropHeight: 158, // 默认生成截图框高度
        fixedBox: true, // 固定截图框大小 不允许改变
        fixed: false, // 是否开启截图框宽高固定比例
        fixedNumber: [7, 5], // 截图框的宽高比例
        full: true, // 是否输出原图比例的截图
        canMoveBox: true, // 截图框能否拖动
        original: true, // 上传图片按照原始比例渲染
        centerBox: true, // 截图框是否被限制在图片里面
        infoTrue: true, // true 为展示真实输出图片宽高 false 展示看到的截图框宽高
      },
    }
  },
  created() {
  },
  methods: {
    beforeUpload(file) {
          // 图片转为base64
          let self = this
          const _URL = window.URL || window.webkitURL
          const image = new Image();
          image.src = _URL.createObjectURL(file);
          self.option.img = ''
          image.onload = function () {
            let base64 = self.transBase64FromImage(image);
            self.option.img = base64
          }
          this.picWidth = 1200
          this.dialogVisible = true
    },
    // 将网络图片转换成base64格式
    transBase64FromImage(image) {
      let canvas = document.createElement("canvas");
      canvas.width = image.width;
      canvas.height = image.height;
      let ctx = canvas.getContext("2d");
      ctx.drawImage(image, 0, 0, image.width, image.height);
      // 可选其他值 image/jpeg
      return canvas.toDataURL("image/png");
    },
    // base64转成files
    transformToFiles(dataurl, filename) {
      var arr = dataurl.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 File([u8arr], filename, { type: mime });
    },
    handleSuccess({data: url, code, msg}, {name}) {
      if (code !== 200) {
        this.$message.error(msg)
      } else {
        this.$emit('handleFile', [{url, name}])
      }
    },
    clearFile() {
      this.$emit('removeImage')
      this.$emit('handleFile', [])
    },
    finish() {
		let _this = this
		this.$refs.cropper.getCropBlob(async (data) => {
			let formData = new FormData();
			console.log(data);
			  if(data){
               var timestamp = new Date().getTime() + '.jpg'
            //  将blob格式转换为文件。File() 构造器创建新的 File 对象实例。
            const newFile = new window.File([data], timestamp);

						formData.append('file',newFile)
						//调用axios上传
						let {data: res} = await axios.post(上传文件地址, formData)
						if(res.code === 200){
							let data = res.data.replace('[','').replace(']','').split(',');
							let imgInfo = {
								name : _this.Name,
								url : data[0]
							};
              this.dialogVisible = false
						}
					} else {
						this.$message.warning('请重新截图')
					}
				})
        _this.$forceUpdate()
			},
    },
  }
}

具体的配置在option里面,finish方法主要是截取并上传,这快用到的是axios进行上传的。

标签:截图,vue,data,截取,element,let,上传,true,image
来源: https://blog.csdn.net/canyi8023/article/details/120371654

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有