vue实现图片裁切
Vue 实现图片裁切的方法
使用第三方库 vue-cropperjs
安装 vue-cropperjs 库:
npm install vue-cropperjs --save
引入并使用组件:
import VueCropper from 'vue-cropperjs';
import 'cropperjs/dist/cropper.css';
export default {
components: {
VueCropper
},
data() {
return {
imgSrc: '',
cropperOptions: {
aspectRatio: 1,
viewMode: 1,
autoCropArea: 0.8
}
};
},
methods: {
handleFileChange(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);
},
getCroppedImage() {
this.$refs.cropper.getCroppedCanvas().toBlob((blob) => {
// 处理裁切后的图片
});
}
}
};
模板部分:
<template>
<div>
<input type="file" accept="image/*" @change="handleFileChange">
<vue-cropper
ref="cropper"
:src="imgSrc"
:options="cropperOptions"
/>
<button @click="getCroppedImage">裁切图片</button>
</div>
</template>
使用原生 Canvas API 实现
创建图片裁切组件:
export default {
data() {
return {
image: null,
canvas: null,
ctx: null,
startX: 0,
startY: 0,
isDragging: false
};
},
mounted() {
this.canvas = this.$refs.canvas;
this.ctx = this.canvas.getContext('2d');
},
methods: {
handleImageUpload(e) {
const file = e.target.files[0];
const reader = new FileReader();
reader.onload = (event) => {
this.image = new Image();
this.image.onload = () => {
this.canvas.width = this.image.width;
this.canvas.height = this.image.height;
this.ctx.drawImage(this.image, 0, 0);
};
this.image.src = event.target.result;
};
reader.readAsDataURL(file);
},
startCrop(e) {
this.startX = e.offsetX;
this.startY = e.offsetY;
this.isDragging = true;
},
cropImage(e) {
if (!this.isDragging) return;
const width = e.offsetX - this.startX;
const height = e.offsetY - this.startY;
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
this.ctx.drawImage(this.image, 0, 0);
this.ctx.strokeStyle = 'red';
this.ctx.strokeRect(this.startX, this.startY, width, height);
},
endCrop() {
this.isDragging = false;
// 获取裁切区域数据
}
}
};
模板部分:
<template>
<div>
<input type="file" @change="handleImageUpload">
<canvas
ref="canvas"
@mousedown="startCrop"
@mousemove="cropImage"
@mouseup="endCrop"
></canvas>
</div>
</template>
使用 Element UI 的 Upload 组件结合裁切功能
安装 Element UI:
npm install element-ui -S
实现代码:
import Vue from 'vue';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
export default {
data() {
return {
dialogVisible: false,
cropImg: '',
cropper: null
};
},
methods: {
handlePreview(file) {
this.dialogVisible = true;
this.$nextTick(() => {
this.cropImg = URL.createObjectURL(file.raw);
this.initCropper();
});
},
initCropper() {
const image = this.$refs.cropImage;
this.cropper = new Cropper(image, {
aspectRatio: 1,
viewMode: 1
});
},
confirmCrop() {
this.cropper.getCroppedCanvas().toBlob((blob) => {
// 处理裁切后的图片
this.dialogVisible = false;
});
}
}
};
模板部分:
<template>
<div>
<el-upload
action="#"
:on-change="handlePreview"
:auto-upload="false"
>
<el-button type="primary">上传图片</el-button>
</el-upload>
<el-dialog :visible.sync="dialogVisible">
<img ref="cropImage" :src="cropImg" style="max-width: 100%">
<span slot="footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="confirmCrop">确定</el-button>
</span>
</el-dialog>
</div>
</template>
注意事项
- 移动端适配需要考虑触摸事件替代鼠标事件
- 裁切比例可以通过设置 aspectRatio 参数控制
- 大图片处理需要考虑性能优化,可以限制最大尺寸
- 裁切结果可以导出为多种格式:Blob、Base64 或 FormData







