Vue中如何实现图片的裁剪和旋转?

在Vue中实现图片的裁剪和旋转功能十分常见,特别是在涉及到图片上传或者处理的场景中,应用广泛。本文将详细介绍在Vue中实现图片裁剪和旋转的具体步骤。

一、图片裁剪

1. 安装并引入插件

要实现图片裁剪功能,首先需要安装一个名为vue-cropper的插件。这个插件是基于Cropper.js开发的,可以方便地实现图片裁剪的功能。安装方法如下:


npm install vue-cropper

在Vue项目中需要使用图片裁剪功能的组件中,引入vue-cropper插件。


import VueCropper from 'vue-cropper'
export default {
  components: {
    VueCropper,
  },
  data() {
    return {
      cropperOptions: {
        // 配置项
      },
    }
  },
}

2. 设置裁剪图片的选项

在引入vue-cropper插件后,需要设置裁剪图片的选项,包括图片源、宽度、高度、裁剪框的比例等,这些选项均可在cropperOptions中进行设置。下面是一份常用的选项设置:


cropperOptions: {
  aspectRatio: 1 / 1, // 裁剪框的比例
  guides: true, // 是否在裁剪框上显示辅助线
  viewMode: 1, // 指定如何显示图片:0表示不限制,1表示限制只能在裁剪框内拖拽移动和缩放
  dragMode: 'crop', // 拖动模式,crop表示裁剪框可拖动,move表示图片可拖动
  cropBoxResizable: true, // 是否允许拖拽裁剪框调整大小
  cropBoxMovable: true, // 是否允许拖拽裁剪框移动
  aspectRatio: 1, // 裁剪框的比例
  autoCrop: true, // 是否默认生成裁剪框
  autoCropArea: 0.8, // 初始化生成裁剪框的尺寸,默认0.8表示图片宽度的80%
  movable: true, // 是否允许移动图片
  zoomable: true, // 是否允许缩放图片
  background: false, // 是否在容器背景上显示网格背景
},

3. 实现图片裁剪功能

设置完裁剪选项后,就可以实现图片裁剪功能了。对于设置好选项的图片,我们可以使用以下代码实现裁剪:


<vue-cropper
  ref="cropper"
  :src="imageSrc"
  :options="cropperOptions"
>
</vue-cropper>
this.$refs.cropper.getCroppedCanvas().toBlob(blob => {
  const formData = new FormData()
  formData.append('file', blob, 'avatar.jpg')
  // 接下来可以将formData上传至服务器
})

在代码中,使用vue-cropper组件渲染图片,并通过getCropperCanvas方法获取裁剪后的图片数据。获取到的图片数据可以通过FormData进行传输。

二、实现图片旋转功能

1. 引入exif-js插件

旋转图片需要使用图片的EXIF信息,而浏览器并不会自动获取图片的EXIF信息。因此,需要在Vue项目中引入一个叫做exif-js的插件,用于获取图片的EXIF信息。可以使用以下方法安装该插件:


npm install exif-js --save

2. 编写获取图片EXIF信息的方法

安装好exif-js插件之后,需要编写一个方法,用于获取图片的EXIF信息。获取EXIF信息的方法代码如下:


import EXIF from 'exif-js'
function getOrientation(file) {
  return new Promise((resolve) => {
    EXIF.getData(file, function () {
      const orientation = EXIF.getTag(this, 'Orientation')
      resolve(orientation)
    })
  })
}

在方法中,使用了Promise异步操作,确保图片EXIF信息的获取不会阻塞页面。

3. 实现图片旋转功能

获取到图片的EXIF信息之后,就可以在程序中实现对图片的旋转操作了。下面是实现图片旋转的代码示例:


async handleRotate() {
  const file = this.$refs.fileInput.files[0]
  const orientation = await getOrientation(file)
  if (![3, 6, 8].includes(orientation)) {
    return
  }
  const img = new Image()
  const reader = new FileReader()
  reader.readAsDataURL(file)
  reader.onload = (e) => {
    img.src = e.target.result
    img.onload = () => {
      const canvas = document.createElement('canvas')
      if ([6, 8].includes(orientation)) {
        canvas.width = img.height
        canvas.height = img.width
      } else {
        canvas.width = img.width
        canvas.height = img.height
      }
      const ctx = canvas.getContext('2d')
      switch (orientation) {
        case 3:
          ctx.rotate(Math.PI)
          ctx.drawImage(img, -canvas.width, -canvas.height, canvas.width, canvas.height)
          break
        case 6:
          ctx.rotate(Math.PI / 2)
          ctx.drawImage(img, 0, -canvas.width, canvas.height, canvas.width)
          break
        case 8:
          ctx.rotate((-1 * Math.PI) / 2)
          ctx.drawImage(img, -canvas.height, 0, canvas.height, canvas.width)
          break
        default:
          ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
      }
      canvas.toBlob((blob) => {
        const formData = new FormData()
        formData.append('file', blob, 'avatar.jpg')
        // 接下来可以将formData上传至服务器
      }, 'image/jpeg', 1)
    }
  }
}

在代码中,通过使用exif-js插件获取到图片的EXIF信息。然后,根据EXIF信息中的orientation值,使用Canvas API将图片旋转到正确的位置,并将旋转后的图片转换为blob数据进行上传。

总结

在Vue中实现图片裁剪和旋转功能需要用到几个重要的插件和API,包括vue-cropper插件、exif-js插件以及Canvas API。按照一定的步骤和方法,就可以实现便捷有效的图片裁剪和旋转功能。