vue3-cropperjs图片裁剪工具-用户上传图片截取-(含预览视频)

效果图

上传图片弹窗预览

对于这个上传图片样式可以参考

官方原代码

官网传送入口 Upload 上传 | Element Plus (element-plus.org)

html 复制代码
<template>
  <el-upload
    class="upload-demo"
    drag
    action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15"
    multiple
  >
    <el-icon class="el-icon--upload"><upload-filled /></el-icon>
    <div class="el-upload__text">
      Drop file here or <em>click to upload</em>
    </div>
    <template #tip>
      <div class="el-upload__tip">
        jpg/png files with a size less than 500kb
      </div>
    </template>
  </el-upload>
</template>

<script setup lang="ts">
import { UploadFilled } from '@element-plus/icons-vue'
</script>

上传图片之后

裁剪图片之后

预览视频

裁剪图片预览视频


操作步骤

安装依赖

npm install cropperjs
npm  i qs    
npm  i axios  
npm i element-plus     

template部分

html 复制代码
<template>
  <div>
    <el-dialog :title="dialogTitle.imgTitle" width="800px" v-model="dialogVisible.imgCropperVisible" :before-close="handleBeforeClose">
      <div v-if="imageSrc" style="display: flex; justify-content: space-between; align-items: center;">

        <!-- Display cropped image or original image if not cropped with background -->
        <div style="width: 50%; padding: 10px; background-color: #f5f5f5; display: flex; justify-content: center; align-items: center;">
          <img ref="previewImage" :src="croppedImageSrc || imageSrc" alt="Preview Image" style="max-width: 100%; height: auto;" />
        </div>

        <!-- Upload image section without background -->
        <div style="width: 50%; padding: 10px; display: flex; justify-content: center; align-items: center;">
          <img ref="uploadImage" :src="imageSrc" alt="Source Image" style="max-width: 100%; height: auto;" />
        </div>
      </div>

      <!-- Centered buttons -->
      <div v-if="imageSrc" style="margin-top: 20px; text-align: center;">
        <el-button type="primary" @click="cropImage">裁剪图片</el-button>
        <el-button @click="clearImage">重新选择</el-button>
        <el-button type="primary" @click="uploadCroppedImage">上传头像</el-button>
      </div>

      <!-- Conditional display for upload component -->
      <el-upload
          v-if="!imageSrc"
          class="upload-demo"
          drag
          action="http://localhost:8888/v1/file/singleUploadFile"
          multiple
          v-model:file-list="fileList"
          limit="1"
          :show-file-list="false"
          :before-upload="beforeUpload"
      >
        <el-icon class="el-icon--upload"><upload-filled /></el-icon>
        <div class="el-upload__text">
          Drop file here or <em>click to upload</em>
        </div>
        <template #tip>
          <div class="el-upload__tip">
            jpg/png files with a size less than 500kb
          </div>
        </template>
      </el-upload>
    </el-dialog>
  </div>
  <div>
    <img :src="BASE_URL+attraction_detail.imageUrl" alt="">
  </div>
</template>

js部分

javascript 复制代码
<script setup>
import { ref, nextTick, onBeforeUnmount } from 'vue';
import { ElMessage } from 'element-plus';
import Cropper from 'cropperjs';
import 'cropperjs/dist/cropper.css';
import axios from 'axios';

const imageSrc = ref(null);
const croppedImageSrc = ref(null);
const dialogTitle = ref({ imgTitle: '上传图片' });
const dialogVisible = ref({ imgCropperVisible: true });
const fileList = ref([]);

const uploadImage = ref(null);
const previewImage = ref(null);
let cropper = null;
const attraction_detail =ref({imageUrl:''})
const beforeUpload = (file) => {
  const isImage = file.type.startsWith('image/');
  if (!isImage) {
    ElMessage.error('只能上传图片文件');
    return false;
  }
  const reader = new FileReader();
  reader.onload = async (e) => {
    imageSrc.value = e.target.result;
    await nextTick();
    initCropper();
  };
  reader.readAsDataURL(file);
  return false;
};

const initCropper = () => {
  if (cropper) {
    cropper.destroy();
  }
  if (!uploadImage.value) return;

  cropper = new Cropper(uploadImage.value, {
    aspectRatio: 1,
    viewMode: 1,
  });
};

const cropImage = () => {
  if (cropper) {
    const canvas = cropper.getCroppedCanvas({
      width: 200,
      height: 200,
    });
    croppedImageSrc.value = canvas.toDataURL('image/png');
  }
};

const clearImage = () => {
  imageSrc.value = null;
  croppedImageSrc.value = null;
  fileList.value = [];
  if (cropper) {
    cropper.destroy();
    cropper = null;
  }
};

const uploadCroppedImage = async () => {
  if (!croppedImageSrc.value) {
    ElMessage.error('请先裁剪图片');
    return;
  }
  try {
    const blob = dataURLToBlob(croppedImageSrc.value);
    const formData = new FormData();
    formData.append('file', blob, 'avatar.png'); // 注意这里的表单字段名应为'file'

    const response = await axios.post('http://localhost:8888/v1/file/singleUploadFile', formData);

    if (response.data) {
      ElMessage.success('上传成功');
      dialogVisible.value.imgVisible = false;
      attraction_detail.value.imageUrl = response.data;
      console.log(response.data)

      console.log("")
    } else {
      ElMessage.error(response.data.msg || '上传失败');
    }
  } catch (error) {
    ElMessage.error('上传失败');
  }
};

const dataURLToBlob = (dataURL) => {
  const arr = dataURL.split(',');
  const mime = arr[0].match(/:(.*?);/)[1];
  const bstr = atob(arr[1]);
  let n = bstr.length;
  const u8arr = new Uint8Array(n);
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n);
  }
  return new Blob([u8arr], { type: mime });
};

onBeforeUnmount(() => {
  if (cropper) {
    cropper.destroy();
  }
});
</script>

css部分

css 复制代码
<style scoped>
.upload-demo .el-upload {
  display: block;
  width: 100%;
  margin-bottom: 20px;
}

.el-upload__text {
  color: #606266;
  font-size: 14px;
  line-height: 22px;
  margin-top: 5px;
}

.el-upload__tip {
  color: #909399;
  font-size: 12px;
  line-height: 1.5;
  margin-top: 7px;
}
</style>
相关推荐
科研online43 分钟前
ArcGIS Pro三维空间分析、专题制图、遥感制图全流程系统教学
arcgis
如影随从1 小时前
04-ArcGIS For JavaScript的可视域分析功能
开发语言·javascript·arcgis·可视域分析
WineMonk3 小时前
ArcGIS Pro SDK (七)编辑 6 检查器
arcgis·c#·gis·arcgis pro sdk
WineMonk1 天前
ArcGIS Pro SDK (七)编辑 10 捕捉
arcgis·c#·gis·arcgis pro sdk
GISer_Jing2 天前
[GIS]WPS地理处理服务
java·javascript·python·arcgis·wps
WineMonk2 天前
ArcGIS Pro SDK (七)编辑 9 使用草图
arcgis·c#·gis·arcgis pro sdk
zui初的梦想3 天前
nodejs--【Express基本使用】
arcgis·express
WineMonk3 天前
ArcGIS Pro SDK (七)编辑 2 启用编辑
arcgis·c#·gis·arcgis pro sdk
陆杨03213 天前
利用Arcgis绘制克吕金插值图
arcgis
RS&3 天前
ARCGIS添加在线地图
arcgis