vue实现图片裁切
Vue 实现图片裁切的方法
使用 vue-cropperjs 库
vue-cropperjs 是一个基于 Cropper.js 的 Vue 封装库,专门用于图片裁切功能。
安装依赖:

npm install vue-cropperjs
基本用法:

<template>
<div>
<input type="file" @change="uploadImage">
<vue-cropper
ref="cropper"
:src="imgSrc"
:aspect-ratio="16/9"
></vue-cropper>
<button @click="cropImage">裁切图片</button>
</div>
</template>
<script>
import VueCropper from 'vue-cropperjs';
import 'cropperjs/dist/cropper.css';
export default {
components: { VueCropper },
data() {
return {
imgSrc: ''
}
},
methods: {
uploadImage(e) {
const file = e.target.files[0];
if (!file.type.includes('image/')) {
alert('请选择图片文件');
return;
}
const reader = new FileReader();
reader.onload = (event) => {
this.imgSrc = event.target.result;
};
reader.readAsDataURL(file);
},
cropImage() {
this.$refs.cropper.getCroppedCanvas().toBlob((blob) => {
// 处理裁切后的图片
}, 'image/jpeg', 0.9);
}
}
}
</script>
使用 cropperjs 直接集成
如果不使用 vue-cropperjs 封装,可以直接集成 Cropper.js:
<template>
<div>
<input type="file" @change="uploadImage">
<img id="image" src="">
<button @click="crop">裁切</button>
</div>
</template>
<script>
import Cropper from 'cropperjs';
import 'cropperjs/dist/cropper.css';
export default {
mounted() {
this.cropper = new Cropper(document.getElementById('image'), {
aspectRatio: 1,
viewMode: 1
});
},
methods: {
uploadImage(e) {
const file = e.target.files[0];
if (!file.type.includes('image/')) return;
const reader = new FileReader();
reader.onload = (event) => {
this.cropper.replace(event.target.result);
};
reader.readAsDataURL(file);
},
crop() {
this.cropper.getCroppedCanvas().toBlob((blob) => {
// 处理裁切结果
});
}
}
}
</script>
自定义简单裁切功能
对于简单的裁切需求,可以完全自己实现:
<template>
<div>
<input type="file" @change="loadImage">
<div class="crop-container" ref="container">
<img :src="imgSrc" ref="image" @load="initCrop">
<div class="crop-box" ref="cropBox"></div>
</div>
<button @click="performCrop">裁切</button>
</div>
</template>
<script>
export default {
data() {
return {
imgSrc: '',
startX: 0,
startY: 0,
isDragging: false
}
},
methods: {
loadImage(e) {
const file = e.target.files[0];
if (!file.type.includes('image/')) return;
const reader = new FileReader();
reader.onload = (event) => {
this.imgSrc = event.target.result;
};
reader.readAsDataURL(file);
},
initCrop() {
const img = this.$refs.image;
const container = this.$refs.container;
const cropBox = this.$refs.cropBox;
// 初始化裁切框位置和大小
cropBox.style.width = '100px';
cropBox.style.height = '100px';
cropBox.style.left = '50px';
cropBox.style.top = '50px';
// 添加拖拽事件
cropBox.addEventListener('mousedown', this.startDrag);
document.addEventListener('mousemove', this.drag);
document.addEventListener('mouseup', this.stopDrag);
},
startDrag(e) {
this.isDragging = true;
this.startX = e.clientX;
this.startY = e.clientY;
},
drag(e) {
if (!this.isDragging) return;
const cropBox = this.$refs.cropBox;
const dx = e.clientX - this.startX;
const dy = e.clientY - this.startY;
cropBox.style.left = (parseInt(cropBox.style.left) + dx) + 'px';
cropBox.style.top = (parseInt(cropBox.style.top) + dy) + 'px';
this.startX = e.clientX;
this.startY = e.clientY;
},
stopDrag() {
this.isDragging = false;
},
performCrop() {
const img = this.$refs.image;
const cropBox = this.$refs.cropBox;
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const x = parseInt(cropBox.style.left);
const y = parseInt(cropBox.style.top);
const width = parseInt(cropBox.style.width);
const height = parseInt(cropBox.style.height);
canvas.width = width;
canvas.height = height;
ctx.drawImage(img, x, y, width, height, 0, 0, width, height);
// 获取裁切后的图片数据
const croppedImage = canvas.toDataURL('image/jpeg');
// 处理裁切结果
}
}
}
</script>
<style>
.crop-container {
position: relative;
display: inline-block;
}
.crop-box {
position: absolute;
border: 2px dashed #fff;
cursor: move;
}
</style>
注意事项
- 移动端适配需要考虑触摸事件
- 裁切比例可以根据需求调整
- 裁切框的交互可以进一步优化,如调整大小
- 性能优化对于大图片很重要,可以考虑压缩或分块处理
- 输出格式支持多种选项,如 PNG、JPEG 等






