基于cropperjs实现Vue图片裁剪压缩上传功能

前段时间项目刚好需要用到图片预览裁剪压缩上传,而对于小白的我并没做过这方面的功能,可谓毫无头绪,于是上网查了下资料,发现了个很不错的插件

好了,废话不多说,先上安装包

npm或bower安装

npm install cropper
# or
bower install cropper

Github地址

 (https://github.com/fengyuanchen/cropperjs)

引入cropperjs

import Cropper from 'cropperjs'

构建截图所要用到的div容器

    
  
Picture
<-- 给input绑定一个监听内容变化的方法,拿到上传的文件 -->

添加遮罩层的样式和让image填充整个容器

.container { z-index: 99; position: fixed; left: 0; top: 0; right: 0; bottom: 0; background:rgba(0,0,0,1);}
#image {max-width: 100%;}
.cancelBtn { position: absolute; left: 5%; bottom: 50px; width: 120px; height: 60px; line-height: 60px;         
 border:none; padding: 0; border-radius: 5px; background:white;}
.sureBtn { position: absolute; right: 5%; bottom: 50px; width: 120px; height: 60px; line-height: 60px;       
 border:none; padding: 0; border-radius: 5px; background:white;}

data

 data () {
  return {
    cropper: '',
    panel: false,
    croppable: false,
    url: '',
  }
},

初始化裁剪框

  let self = this
  this.cropper = new Cropper(image, {
    aspectRatio: 1, // 设置裁切框的宽高比
    viewMode: 2, // 限制裁剪框不超过画布的大小
    dragMode: 'move', // 在裁剪框外移动会移动原图
    background: false, // 显示容器的网格背景
    zoomable: true, // 是否可缩放图像
    autoCropArea: 1, // 裁剪区域的比例
    ready: function () {
      self.croppable = true
    }
  })

本地图片上传到canvas

updateHeadImg (e) {
  let files = e.target.files || e.dataTransfer.files
  let pattern = /(\.*.jpg$)|(\.*.png$)|(\.*.jpeg$)|(\.*.gif$)|(\.*.bmp$)/
  if (!files.length) return
  if (!pattern.test(files[0].name)) {
    this.pop = '仅支持jpg/jpeg/png/gif/bmp格式的照片'
    this.layer = 1
    return false
  }
  this.panel = true
  // 获取上传图片文件的url
  this.url = this.getObjectURL(files[0])
  // 每次替换图片要重新得到新的url
  if (this.cropper) {
    this.cropper.replace(this.url) // 替换图像的src并重建裁剪器
  }
  this.panel = true
},

获取上传图片文件的url

getObjectURL (file) {
  var url = null
  if (window.createObjectURL !== undefined) { // basic
    url = window.createObjectURL(file)
  } else if (window.URL !== undefined) { // mozilla(firefox)
    url = window.URL.createObjectURL(file)
  } else if (window.webkitURL !== undefined) { // webkit or chrome
    url = window.webkitURL.createObjectURL(file)
  }
  return url
},

裁剪

crop () {
  this.panel = false
  let croppedCanvas
  let roundedCanvas
  if (!this.croppable) {
    return
  }
  // Crop
  croppedCanvas = this.cropper.getCroppedCanvas()
  // Round
  roundedCanvas = this.getRoundedCanvas(croppedCanvas)
  // 将图片压缩 70%
  this.headerImage = roundedCanvas.toDataURL('image/jpeg', 0.7)
  // 上传到服务器
  this.postImg()
},

取消裁剪

cancelCrop () {
  this.panel = false
},

Round

getRoundedCanvas (sourceCanvas) {
  var canvas = document.createElement('canvas')
  var context = canvas.getContext('2d')
  var width = sourceCanvas.width
  var height = sourceCanvas.height
  canvas.width = width
  canvas.height = height
  context.imageSmoothingEnabled = true // 控制图像的缩放行为
  context.drawImage(sourceCanvas, 0, 0, width, height)
  context.globalCompositeOperation = 'destination-in' // 在源图像中显示目标图像。只有源图像内的目标图像部分会被显示,源图像是透明的。
  context.beginPath()
  context.arc(width / 2, height / 2, Math.min(width, height) / 2, 0, 2 * Math.PI, true)
  context.fill()
  return canvas
},

上传到服务器

postImg () {
  // 这边写图片的上传
  axios.post('接口', {'图片地址': this.headerImage}).then((res) => {
    console.log('成功')
  })
},

当初以为这样就完事了,可发现当再次进行上传的时候发现图片会下滑,翻看了一下文档,发现官方是使用动态添加裁剪容器的方法进行操作的。
既然知道了每执行一次都要重新渲染画布,那就很简单了,我们把初始化事件添加到watch上,当重新选择的时候重新渲染画布

/* 把画布清空 */
  if (document.querySelector('.cropper-container')) {
    document.querySelector('.cropper-container').remove()
  }
  this.cropper = ''
  // 重新渲染画布
  let image = document.getElementById('image')
  let self = this
  this.cropper = new Cropper(image, {
    aspectRatio: this.edEle.width / this.edEle.height, // 设置裁切框的宽高比
    viewMode: 2, // 限制裁剪框不超过画布的大小
    dragMode: 'move', // 在裁剪框外移动会移动原图
    background: false, // 显示容器的网格背景
    zoomable: true, // 是否可缩放图像
    autoCropArea: 1, // 裁剪区域的比例
    ready: function () {
      self.croppable = true
    }
  })

小白初来驾到,如有错误请告知,让我们互相学习学习

你可能感兴趣的:(基于cropperjs实现Vue图片裁剪压缩上传功能)