当前位置:首页 > 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 原生实现

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

<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
分享给朋友:

相关文章

vue设计与实现目录

vue设计与实现目录

以下是《Vue设计与实现》一书的典型目录结构(根据常见技术书籍及Vue核心内容整理): 响应式系统 响应式数据的基本原理 依赖收集与触发更新 实现简易响应式系统 Proxy与Refle…

vue实现主题

vue实现主题

Vue 实现主题的方法 使用 CSS 变量动态切换主题 定义全局 CSS 变量,通过修改这些变量实现主题切换。在 Vue 的根组件或全局样式中定义变量: :root { --primary-co…

vue实现通知

vue实现通知

Vue 实现通知功能的方法 使用 Vue 实现通知功能可以通过多种方式实现,以下是一些常见的方法: 使用 Vue 的全局事件总线 在 Vue 中可以通过事件总线实现通知功能。创建一个全局事件总线,…

vue实现类别

vue实现类别

Vue 实现类别的几种方法 在 Vue 中实现类别功能可以通过多种方式完成,以下是一些常见的方法: 使用 v-bind:class 动态绑定类名 通过对象语法或数组语法动态绑定类名,根据条件添加或移…

vue实现rtc

vue实现rtc

Vue 实现 RTC 的步骤 安装依赖 在 Vue 项目中安装 WebRTC 相关依赖,如 simple-peer 或 peerjs,用于简化 WebRTC 的实现。 运行以下命令安装 simple-…

vue实现登出

vue实现登出

实现Vue登出功能 登出功能通常涉及清除用户会话、令牌或本地存储的数据,并重定向到登录页面。以下是几种常见的实现方式: 清除用户令牌和状态 在Vuex的store中定义一个logout mutat…