Vue 中如何实现图片裁剪及压缩?

1. 前言

随着互联网的发展,页面上的图片也越来越重要,而对于一些大尺寸的图片,会让页面加载变慢,并且占用大量的带宽。因此,对于图片的裁剪和压缩是非常有必要的。本文介绍如何使用 Vue.js 实现图片的裁剪和压缩。

2. 图片裁剪

2.1 前端图片裁剪方案

前端图片裁剪方案一般有两种:一种是使用 HTML5 的 canvas 元素,另一种是使用第三方库。在本文中,我们将使用第三方库:VueCropper。

2.2 VueCropper 图片裁剪组件

VueCropper 是一个 Vue.js 的图片裁剪组件,底层使用 Cropper.js 实现。它支持预览、旋转、裁剪等功能,并且可以直接输出裁剪后的图片数据,非常方便。以下是它的使用方法:

// 安装

npm install vue-cropper --save

// 引入

import VueCropper from 'vue-cropper'

// 注册组件

Vue.component(VueCropper);

在使用的时候,需要先在 HTML 中设置一个容器,然后在 Vue 实例中使用组件:

<div id="app">

<vue-cropper ref="cropper"></vue-cropper>

</div>

new Vue({

el: '#app',

mounted: function () {

// 初始化配置

var options = {

aspectRatio: 16 / 9,

viewMode: 1,

preview: '.img-preview'

};

// 初始化 Cropper

this.$refs.cropper.init(options);

}

});

以上代码中,我们首先在 HTML 中设置了一个容器(div#app),然后在组件中引入了 VueCropper,使用 ref 指令指向了组件实例($refs.cropper)。在 Vue 实例中,我们通过调用实例上的 init 方法来初始化 Cropper,init 方法接收一个配置对象作为参数,可以配置裁剪框的大小、纵横比、预览位置等参数。

2.3 VueCropper 图片裁剪示例

下面我们来看一个完整的使用示例:

<template>

<div>

<h3>图片预览</h3>

<img :src="imagePreview" style="max-width:100%;">

<h3>图片裁剪</h3>

<div class="cropper">

<vue-cropper ref="cropper" :guides="false"></vue-cropper>

</div>

<button @click="getCropData">点击获取裁剪后的图片</button>

</div>

</template>

<script>

import VueCropper from 'vue-cropper'

export default {

name: 'App',

components: {

VueCropper

},

data () {

return {

imagePreview: '',

cropData: ''

}

},

methods: {

// 选择图片

handleSelectImage () {

const fileInput = this.$refs.fileInput;

fileInput.click();

},

// 存储图片

handleUploadImage (event) {

const file = event.target.files[0];

const reader = new FileReader();

reader.onload = e => {

this.imagePreview = e.target.result;

this.$refs.cropper.setImage(this.imagePreview);

}

reader.readAsDataURL(file);

},

// 获取裁剪后的图片

getCropData () {

this.cropData = this.$refs.cropper.getCroppedCanvas().toDataURL();

}

}

}

</script>

上述代码中,我们首先在 HTML 中设置了一个选取图片的按钮,一个图片预览区域,还有一个 Cropper 组件。在 Vue 实例中,我们定义了两个方法:handleSelectImage 和 handleUploadImage,分别用于选择文件和读取文件。在 handleUploadImage 中,我们使用了 FileReader 对象读取文件,读取完成后将结果赋值给 imagePreview,并将图片绑定到 Cropper 中(通过调用视频上的 setImage 方法)。

最后我们定义了一个按钮,用于获取裁剪后的图片。在 getCropData 方法中,我们调用了 Cropper 实例上的 getCroppedCanvas 方法,获取到了裁剪后的 Canvas 对象(可以在后续步骤中将 Canvas 转成图片文件)。

3. 图片压缩

3.1 前端图片压缩方案

前端图片压缩方案一般有两种:一种是使用 HTML5 的 canvas 元素,另一种是使用第三方库。在本文中,我们将使用第三方库:compressorjs。

3.2 使用 compressorjs 进行图片压缩

compressorjs 是一个轻量级的前端图片压缩库,支持 JPEG、PNG 和 WebP 格式的压缩。以下是它的使用方法:

// 安装

npm install compressorjs --save

// 引入

import Compressor from 'compressorjs'

// 使用

new Compressor(file, {

quality: 0.6,

success (result) {

// do something

}

})

compressorjs 接收两个参数:文件对象和配置对象。配置对象中可以指定图片的质量(quality),缩放比例(scale)、目标宽度和高度(width 和 height)等参数。

压缩成功后,compressorjs 会将压缩后的图片作为 Blob 对象传入 success 回调函数。

3.3 图片裁剪和压缩示例

下面我们来看一个完整的使用示例:

<template>

<div>

<h3>选择图片</h3>

<input type="file" ref="fileInput" style="display: none;" @change="handleUploadImage">

<button @click="handleSelectImage">点击选择图片</button>

<h3>图片预览</h3>

<img :src="imagePreview" style="max-width:100%;">

<h3>图片裁剪</h3>

<div class="cropper">

<vue-cropper ref="cropper"></vue-cropper>

</div>

<button @click="getCropData">点击获取裁剪后的图片</button>

<h3>图片压缩</h3>

<img :src="compressedImage" v-if="compressedImage" style="max-width:100%;">

</div>

</template>

<script>

import VueCropper from 'vue-cropper'

import Compressor from 'compressorjs'

export default {

name: 'App',

components: {

VueCropper

},

data () {

return {

imagePreview: '',

compressedImage: '',

cropData: ''

}

},

methods: {

// 选择图片

handleSelectImage () {

const fileInput = this.$refs.fileInput;

fileInput.click();

},

// 存储图片

handleUploadImage (event) {

const file = event.target.files[0];

const reader = new FileReader();

reader.onload = e => {

this.imagePreview = e.target.result;

this.$refs.cropper.setImage(this.imagePreview);

}

reader.readAsDataURL(file);

},

// 获取裁剪后的图片

getCropData () {

const canvas = this.$refs.cropper.getCroppedCanvas();

canvas.toBlob(blob => {

new Compressor(blob, {

quality: 0.6,

success: result => {

this.compressedImage = window.URL.createObjectURL(result);

}

});

});

}

}

}

</script>

以上代码中,我们在原来的基础上新增了一个 compressedImage 变量,用于存储压缩后的图片。在 getCropData 方法中,我们先通过调用 getCroppedCanvas 方法获取到裁剪后的 Canvas 对象,然后将它转化成 Blob 对象,再使用 Compressor 压缩成指定大小。最后,我们通过调用 window.URL.createObjectURL 方法将压缩后的 Blob 对象生成一个链接,将这个链接绑定到 HTML 中的 img 元素上即可。

4. 总结

图片裁剪和压缩是前端开发中非常常见的需求,在 Vue.js 中,我们可以使用 VueCropper 和 compressorjs 等第三方库来实现这一功能。VueCropper 拥有较为完善的图片裁剪功能,而 compressorjs 则是轻量级的前端图片压缩库,易于使用。在使用时,根据具体需求选择合适的库即可。