vue3 使用vue-cropper图片裁剪

一、安装

npm install vue-cropper@next

二、引入 Vue Cropper

1.组件引入

import 'vue-cropper/dist/index.css'
import {
    
     VueCropper }  from "vue-cropper";

2.全局引入

import VueCropper from 'vue-cropper'; 
import 'vue-cropper/dist/index.css'

const app = createApp(App)
app.use(VueCropper)
app.mount('#app')

三、页面中使用

html

<template>
  <div class="drawing-container">
    <vueCropper
        ref="cropper"
        :img="option.img"
        :outputSize="option.outputSize"
        :outputType="option.outputType"
        :info="option.info"
        :canScale="option.canScale"
        :autoCrop="option.autoCrop"
        :autoCropWidth="option.autoCropWidth"
        :autoCropHeight="option.autoCropHeight"
        :fixedBox="option.fixedBox"
        :fixed="option.fixed"
        :fixedNumber="option.fixedNumber"
        :canMove="option.canMove"
        :canMoveBox="option.canMoveBox"
        :original="option.original"
        :centerBox="option.centerBox"
        :infoTrue="option.infoTrue"
        :full="option.full"
        :enlarge="option.enlarge"
        :mode="option.mode"
    ></vueCropper>

    <div class="update-img-btn">
      <el-upload
          class="avatar-uploader"
          action=""
          accept="image/png, image/jpeg"
          :show-file-list="false"
          :on-change="beforeAvatarUpload"
          :auto-upload="false"
      >
        <el-link :underline="false" type="primary">Select a photo</el-link>
      </el-upload>
      <el-button type="primary" @click="handleSaveAvatar">Save</el-button>
    </div>
  </div>
</template>

js

<script setup>
import {
    
    reactive, ref, toRaw} from "vue";
import {
    
    fileToBase64Async} from "../../utils/fileUtils.js";

const cropper=ref()

let option=reactive( {
    
    
      img: '', // 裁剪图片的地址 url 地址, base64, blob
      outputSize: 1, // 裁剪生成图片的质量
      outputType: 'jpeg', // 裁剪生成图片的格式 jpeg, png, webp
      info: true, // 裁剪框的大小信息
      canScale: false, // 图片是否允许滚轮缩放
      autoCrop: true, // 是否默认生成截图框
      autoCropWidth: 150, // 默认生成截图框宽度
      autoCropHeight: 150, // 默认生成截图框高度
      fixedBox: false, // 固定截图框大小 不允许改变
      fixed: true, // 是否开启截图框宽高固定比例
      fixedNumber: [1, 1], // 截图框的宽高比例 [ 宽度 , 高度 ]
      canMove: true, // 上传图片是否可以移动
      canMoveBox: true, // 截图框能否拖动
      original: false, // 上传图片按照原始比例渲染
      centerBox: true, // 截图框是否被限制在图片里面
      infoTrue: true, // true 为展示真实输出图片宽高 false 展示看到的截图框宽高
      full: true, // 是否输出原图比例的截图
      enlarge: '1', // 图片根据截图框输出比例倍数
      mode: 'contain' // 图片默认渲染方式 contain , cover, 100px, 100% auto
})

const beforeAvatarUpload=async (file) => {
    
    
  option.img = await toRaw(fileToBase64Async(file.raw))
}
const handleSaveAvatar=()=>{
    
    
  cropper.value.getCropBlob((data)=>{
    
    
  	//此处为上传图片逻辑
    console.log(data)
  })
}
</script>

fileUtils

/**
 * file 转Base64 DataURL
 * @param {File} file
 * @returns
 */
export function fileToBase64Async(file) {
    
    
    return new Promise((resolve, reject) => {
    
    
        let reader = new FileReader();
        reader.readAsDataURL(file);
        reader.onload = (e) => {
    
    
            resolve(e.target.result);
        };
    });
}

/**
 * 解析base64中的数据信息
 * @param {String} base64
 * @returns
 */
function parseBase64(base64) {
    
    
    let arr = base64.split(","),
        mime = arr[0].match(/:(.*?);/)[1];

    return {
    
    
        mime,
        data: arr[1],
    };
}

/**
 * base64转Uint8
 * @param {String} base64
 * @returns
 */
function base64ToUint8Array(base64) {
    
    
    let parsedBase64 = parseBase64(base64);

    let bstr = atob(parsedBase64.data);
    let n = bstr.length;
    let u8arr = new Uint8Array(n);

    while (n--) {
    
    
        u8arr[n] = bstr.charCodeAt(n);
    }

    return u8arr;
}

/**
 * 将base64转换为blob
 * @param {String} base64
 * @returns
 */
function base64ToBlob(base64) {
    
    
    let parsedBase64 = parseBase64(base64);
    let u8arr = base64ToUint8Array(base64);
    return new Blob([u8arr], {
    
     type: parsedBase64.mime });
}

/**
 * 将blob转换为file
 * @param {Blob} blobData
 * @returns
 */
function blobToFile(blobData) {
    
    
    let date = new Date();

    blobData.lastModifiedDate = date;
    blobData.lastModified = date.getTime();
    blobData.name = blobData.type.replace("/", ".");

    return blobData;
}

/**
 * base64 转 File
 * @param {String} base64
 * @returns
 */
export function base64ToFile(base64) {
    
    
    let file = null;

    // 浏览器兼容
    if (window.File != undefined) {
    
    
        let parsedBase64 = parseBase64(base64);
        let u8arr = base64ToUint8Array(base64);
        file = new File([u8arr], parsedBase64.mime.replace("/", "."), {
    
    
            type: parsedBase64.mime,
        });
    } else {
    
    
        file = blobToFile(base64ToBlob(base64));
    }

    return file;
}

猜你喜欢

转载自blog.csdn.net/qq_43548590/article/details/128199420