返回

探索Vue-Cropper: 轻松实现图片剪裁上传

前端

1. 引入依赖

npm install vue-cropper --save
npm install element-ui --save

2. 安装Element UI

vue add element-ui

3. 创建剪裁组件

<template>
  <div class="cropper">
    <el-upload
      ref="upload"
      :accept="accept"
      :show-file-list="false"
      :on-change="changeUpload"
    >
      <button class="el-button el-button--primary">选择图片</button>
    </el-upload>
    <vue-cropper
      ref="cropper"
      v-if="imageUrl"
      :image="imageUrl"
      :auto-crop="true"
      :crop="crop"
      :fixed="true"
      :movable="false"
      :scalable="false"
      :zoomable="false"
      @ready="onReady"
      @crop="onCrop"
    />
  </div>
</template>

<script>
import Cropper from 'vue-cropper';
import { ElMessage } from 'element-ui';

export default {
  name: 'ImageCropper',
  components: {
    Cropper,
  },
  data() {
    return {
      imageUrl: null,
      crop: {
        x: 0,
        y: 0,
        width: 1,
        height: 1,
      },
    };
  },
  methods: {
    changeUpload(file) {
      const reader = new FileReader();
      reader.onload = () => {
        this.imageUrl = reader.result;
      };
      reader.readAsDataURL(file.raw);
    },
    onReady() {
      this.$refs.cropper.reset();
    },
    onCrop(data) {
      this.crop = {
        x: data.x,
        y: data.y,
        width: data.width,
        height: data.height,
      };
    },
    async submit() {
      const croppedImage = await this.$refs.cropper.getCroppedCanvas().toBlob();
      const formData = new FormData();
      formData.append('image', croppedImage, 'image.png');

      try {
        const res = await axios.post('/api/upload-image', formData);
        ElMessage.success(res.data.message);
      } catch (err) {
        ElMessage.error(err.message);
      }
    },
  },
};
</script>

<style scoped>
.cropper {
  position: relative;
}

.cropper button {
  margin-right: 10px;
}

.cropper .vue-cropper {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}
</style>

4. 在组件中使用

<template>
  <image-cropper />
</template>

<script>
import ImageCropper from '@/components/ImageCropper';

export default {
  name: 'App',
  components: {
    ImageCropper,
  },
};
</script>

5. 上传图片

async submit() {
  const croppedImage = await this.$refs.cropper.getCroppedCanvas().toBlob();
  const formData = new FormData();
  formData.append('image', croppedImage, 'image.png');

  try {
    const res = await axios.post('/api/upload-image', formData);
    ElMessage.success(res.data.message);
  } catch (err) {
    ElMessage.error(err.message);
  }
}

6. 服务器端处理

<?php

if (isset($_FILES['image'])) {
  $file = $_FILES['image'];

  // Generate a unique filename
  $filename = uniqid() . '.png';

  // Save the cropped image to the server
  move_uploaded_file($file['tmp_name'], 'uploads/' . $filename);

  // Return a success message
  echo json_encode(['message' => 'Image uploaded successfully.']);
} else {
  // Return an error message
  echo json_encode(['error' => 'No image uploaded.']);
}

总结

通过结合Element-UI和Vue-Cropper库,我们可以轻松实现图片剪裁上传功能。这种方法不仅操作简单,而且可以自定义剪裁区域,满足不同的需求。