当前位置:首页 > VUE

vue实现图片裁切

2026-01-18 01:43:55VUE

Vue 实现图片裁切的方法

使用 vue-cropperjs 库

vue-cropperjs 是一个基于 Cropper.js 的 Vue 封装库,专门用于图片裁切功能。

安装依赖:

vue实现图片裁切

npm install vue-cropperjs

基本用法:

vue实现图片裁切

<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>

注意事项

  1. 移动端适配需要考虑触摸事件
  2. 裁切比例可以根据需求调整
  3. 裁切框的交互可以进一步优化,如调整大小
  4. 性能优化对于大图片很重要,可以考虑压缩或分块处理
  5. 输出格式支持多种选项,如 PNG、JPEG 等

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

相关文章

vue实现单选

vue实现单选

Vue 实现单选功能 在 Vue 中实现单选功能可以通过多种方式完成,以下是几种常见的方法: 使用 v-model 绑定单选按钮 通过 v-model 绑定一个变量,可以实现单选功能。单选按钮的 v…

项目基于vue实现

项目基于vue实现

基于Vue实现项目的关键方法 搭建基础环境 安装Node.js和npm/yarn,确保开发环境具备运行Vue的能力。通过Vue CLI快速初始化项目结构,选择所需配置(如Babel、Router、Vu…

vue实现按钮刷新

vue实现按钮刷新

Vue 实现按钮刷新功能 在 Vue 中实现按钮刷新功能可以通过多种方式实现,具体取决于刷新需求是局部刷新还是全局刷新。以下是几种常见的方法: 使用 window.location.reload()…

vue实现横向导航

vue实现横向导航

vue实现横向导航的方法 使用Flex布局实现横向导航 在Vue中可以通过Flex布局快速实现横向导航。创建一个组件,使用display: flex和flex-direction: row属性使导航项…

vue实现关键词轮播

vue实现关键词轮播

Vue 实现关键词轮播 基础实现方案 使用 Vue 的 v-for 和 setInterval 实现基础轮播效果: <template> <div class="keywor…

vue中实现显示和隐藏

vue中实现显示和隐藏

控制显示与隐藏的方法 在Vue中实现元素的显示和隐藏可以通过多种方式完成,以下是常见的几种方法: 1. 使用v-if指令v-if根据条件动态添加或移除DOM元素,适合需要频繁切换的场景。当条件为fa…