当前位置:首页 > VUE

vue实现图片裁剪

2026-02-18 09:28:41VUE

Vue 实现图片裁剪的方法

使用第三方库 vue-cropperjs

安装 vue-cropperjs 库:

npm install vue-cropperjs

在 Vue 组件中引入并使用:

<template>
  <div>
    <input type="file" @change="uploadImage" accept="image/*">
    <vue-cropper
      ref="cropper"
      :src="imgSrc"
      :aspect-ratio="16/9"
      :auto-crop-area="0.8"
    ></vue-cropper>
    <button @click="cropImage">裁剪图片</button>
    <img :src="croppedImage" v-if="croppedImage">
  </div>
</template>

<script>
import VueCropper from 'vue-cropperjs';
import 'cropperjs/dist/cropper.css';

export default {
  components: {
    VueCropper
  },
  data() {
    return {
      imgSrc: '',
      croppedImage: ''
    };
  },
  methods: {
    uploadImage(e) {
      const file = e.target.files[0];
      if (!file) return;

      const reader = new FileReader();
      reader.onload = (event) => {
        this.imgSrc = event.target.result;
      };
      reader.readAsDataURL(file);
    },
    cropImage() {
      this.$refs.cropper.getCroppedCanvas().toBlob((blob) => {
        const reader = new FileReader();
        reader.onload = (event) => {
          this.croppedImage = event.target.result;
        };
        reader.readAsDataURL(blob);
      });
    }
  }
};
</script>

使用 HTML5 Canvas 原生实现

创建自定义图片裁剪组件:

vue实现图片裁剪

<template>
  <div>
    <input type="file" @change="handleFileChange" accept="image/*">
    <div v-if="imageLoaded">
      <canvas ref="canvas" @mousedown="startCrop" @mousemove="drawCrop" @mouseup="endCrop"></canvas>
      <button @click="crop">裁剪</button>
      <img :src="croppedImage" v-if="croppedImage">
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      image: null,
      imageLoaded: false,
      canvas: null,
      ctx: null,
      isCropping: false,
      startX: 0,
      startY: 0,
      endX: 0,
      endY: 0,
      croppedImage: ''
    };
  },
  mounted() {
    this.canvas = this.$refs.canvas;
    this.ctx = this.canvas.getContext('2d');
  },
  methods: {
    handleFileChange(e) {
      const file = e.target.files[0];
      if (!file) return;

      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.imageLoaded = true;
        };
        this.image.src = event.target.result;
      };
      reader.readAsDataURL(file);
    },
    startCrop(e) {
      this.isCropping = true;
      const rect = this.canvas.getBoundingClientRect();
      this.startX = e.clientX - rect.left;
      this.startY = e.clientY - rect.top;
    },
    drawCrop(e) {
      if (!this.isCropping) return;

      const rect = this.canvas.getBoundingClientRect();
      this.endX = e.clientX - rect.left;
      this.endY = e.clientY - rect.top;

      this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
      this.ctx.drawImage(this.image, 0, 0);
      this.ctx.strokeStyle = 'red';
      this.ctx.lineWidth = 2;
      this.ctx.strokeRect(
        this.startX,
        this.startY,
        this.endX - this.startX,
        this.endY - this.startY
      );
    },
    endCrop() {
      this.isCropping = false;
    },
    crop() {
      const width = this.endX - this.startX;
      const height = this.endY - this.startY;
      const cropCanvas = document.createElement('canvas');
      cropCanvas.width = width;
      cropCanvas.height = height;
      const cropCtx = cropCanvas.getContext('2d');
      cropCtx.drawImage(
        this.canvas,
        this.startX,
        this.startY,
        width,
        height,
        0,
        0,
        width,
        height
      );
      this.croppedImage = cropCanvas.toDataURL('image/png');
    }
  }
};
</script>

注意事项

  • 对于移动端支持,需要添加 touch 事件处理
  • 考虑添加缩放和旋转功能时,需要更复杂的坐标变换计算
  • 生产环境中建议使用成熟的第三方库以获得更好的兼容性和功能支持
  • 大图片处理时需要考虑性能优化,可能需要使用 Web Worker

两种方法各有优缺点:vue-cropperjs 功能全面但依赖第三方库,原生实现更轻量但需要自行处理更多细节。根据项目需求选择合适方案。

标签: 图片vue
分享给朋友:

相关文章

vue实现autocomplete

vue实现autocomplete

Vue 实现 Autocomplete 功能 Vue 中实现 Autocomplete(自动完成)功能可以通过自定义组件或使用现有库完成。以下是几种常见方法: 方法一:使用 Vue 原生实现 创建…

vue 实现href

vue 实现href

Vue 实现 href 的方法 在 Vue 中实现 href 功能可以通过多种方式,具体取决于需求场景。以下是几种常见的方法: 使用 <a> 标签 直接使用 HTML 的 <a&g…

vue 实现脚本

vue 实现脚本

Vue 实现脚本的方法 Vue.js 提供了多种方式来实现脚本功能,包括组件内脚本、混入(Mixins)、插件(Plugins)以及自定义指令等。以下是常见的实现方式: 组件内脚本 在 Vue 单文…

vue实现123456

vue实现123456

Vue 实现数字 123456 的显示 在 Vue 中显示数字 123456 非常简单,可以通过以下方法实现: 方法一:直接在模板中显示 <template> <div>…

vue实现兼容

vue实现兼容

Vue 兼容性实现方案 Vue.js 的兼容性主要涉及对不同浏览器、Vue 版本以及第三方库的支持。以下是常见的兼容性解决方案: 浏览器兼容性 使用 Babel 转换 ES6+ 代码为 ES5 语…

vue最佳实现

vue最佳实现

Vue 最佳实践 组件设计 组件应遵循单一职责原则,每个组件只负责一个功能模块。命名采用 PascalCase(如 UserProfile.vue),模板中使用 kebab-case(如 <us…