​​Vue-Cropper​​ 是一个基于 Vue.js 的图片裁剪组件库,专为 Web 应用设计。当你在网上搜索的时候发现还有一个叫cropper的库,下面是他们的区别:

二、快速上手

//npm 安装
npm install vue-cropper
//yarn 安装
yarn add vue-cropper

对该插件进行封装,使用vue3 + ts

<script lang="ts" setup>
import 'vue-cropper/dist/index.css'
import { VueCropper } from 'vue-cropper' const emit = defineEmits(['realTime'])
const props = defineProps({
width: { type: Number, default: 640 },
height: { type: Number, default: 740 }
}) const options = reactive({
img: '',
autoCrop: true,
autoCropWidth: 640,
autoCropHeight: 740,
fillColor: '#fff', // 裁剪框填充颜色
fixedBox: true // 固定裁剪框
}) const cropperInstance = ref()
const blobData = ref(new Blob()) const init = () => {
options.img = ''
} const selectImg = async (e: Event) => {
const file = (e.target as HTMLInputElement).files?.[0]
if (!file) return const reader = new FileReader()
reader.onload = async e => {
const img = new Image()
img.onload = async () => {
// 强制放大到最小尺寸
const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')! // 设置 canvas 尺寸
canvas.width = img.width
canvas.height = img.height
ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
options.img = canvas.toDataURL()
await nextTick()
// 等待 DOM 更新后设置裁剪框
setFixedCropBox()
}
img.src = e.target!.result as string
}
reader.readAsDataURL(file)
} const setFixedCropBox = () => {
if (!cropperInstance.value?.cropper) return // 正确访问cropper实例
const cropper = cropperInstance.value.cropper // 获取容器真实尺寸
const containerWidth = cropper.containerData.width
const containerHeight = cropper.containerData.height // 计算居中位置
const left = (containerWidth - props.width) / 2
const top = (containerHeight - props.height) / 2 // 正确调用方法
cropper.setCropBoxData({
width: props.width,
height: props.height,
left,
top
})
} // 实时预览
const realTime = (data: any) => {
emit('realTime', data.html)
} // 获取截图的数据 getCropBlob => blob数据
const tailoring = (): Promise<Blob> => {
return new Promise((resolve, reject) => {
if (!cropperInstance.value) {
reject(new Error('裁剪组件未初始化'))
return
} cropperInstance.value.getCropBlob((data: Blob) => {
if (data) {
blobData.value = data
resolve(data)
} else {
reject(new Error('裁剪失败,未获取到 Blob'))
}
})
})
} // 旋转
const rotateLeft = () => {
if (!cropperInstance.value) return
cropperInstance.value.rotateLeft()
} const rotateRight = () => {
if (!cropperInstance.value) return
cropperInstance.value.rotateRight()
} onMounted(() => {
if (props.width && props.height) {
options.autoCropWidth = props.width
options.autoCropHeight = props.height
}
}) defineExpose({ options, selectImg, realTime, tailoring, blobData, init, rotateLeft, rotateRight })
</script> <template>
<vue-cropper
ref="cropperInstance"
:img="options.img"
:autoCrop="options.autoCrop"
:autoCropWidth="options.autoCropWidth"
:autoCropHeight="options.autoCropHeight"
:fixedBox="options.fixedBox"
:fillColor="options.fillColor"
@real-time="realTime"
/>
</template>

父组件进行使用

   <el-form-item>
            <div class="flex items-center gap-10px">
                <span>公告图片</span>
                <!-- <el-button size="small" type="primary" class="mx-0" @click="openUpload">
                    <el-icon class="mr-3px"><Upload /></el-icon> 上传</el-button
                > -->
                <el-button :type="form.backgroundImage ? 'success' : 'primary'" @click="openUpload">
                    <el-icon class="mr-3px"><Upload /></el-icon>
                    {{ form.backgroundImage ? '重新上传' : '上传' }}</el-button
                >
                <el-button class="mx-0" type="danger" :icon="Delete" @click="form.backgroundImage = ''"></el-button>
                <div class="text-slate text-xs">建议:宽高640*740,png或jpg/jpeg格式,小于2M</div>
            </div>
            <input type="file" name="" ref="uploadRef" class="hidden" @change="handleCaptureUpload" />
        </el-form-item>
        <!-- 图片预览裁剪 -->
        <el-dialog
            v-model="showCaptureVisible"
            title="图片预览裁剪"
            width="50%"
            @close="closeCapture"
            top="5vh"
            draggable
            destroy-on-close
        >
            <div class="w-full h-78vh mt-10px flex justify-center items-center">
                <Cropper ref="cropper" :height="740" :width="640"></Cropper>
            </div>
            <template #footer>
                <span class="dialog-footer">
                    <el-button :icon="RefreshRight" type="info" @click="handleRotateRight"></el-button>
                    <el-button :icon="RefreshLeft" type="info" @click="handleRotateLeft"></el-button>
                    <el-button type="info" @click="closeCapture">关闭</el-button>
                    <el-button type="primary" @click="tailoring" :loading="cropperLoading">确定</el-button>
                </span>
            </template>
        </el-dialog>
<script setup lang="ts">
 
const uploadRef = ref()
const showCaptureVisible = ref(false)
const cropper = ref()
// 上传图片loading
const { loading: cropperLoading } = useLoading()
// 裁剪图片
const tailoring = async () => {
    //文件大小
    cropperLoading.value = true
    const blob = await cropper.value.tailoring()
    if (blob.size > 2 * 1024 * 1024) {
        cropperLoading.value = false
        warningMessage('图片大小超出2M限制')
        return
    }
    const formData = new FormData()
    formData.append('file', blob, 'cropped.jpg')
    formData.append('accountId', regionSelect.brandId as string)
    uploadImage(formData) // 这里调用后台api
        .then(
            async res => {
                form.value.backgroundImage = res.data
                doSuccess('上传成功')
            },
            () => {
                ElNotification({
                    type: 'warning',
                    message: '图片上传失败'
                })
            }
        )
        .finally(() => {
            formRef.value?.validate().catch(() => {})
            // 关闭裁剪
            showCaptureVisible.value = false
            cropperLoading.value = false
        })
}
// 图片旋转
const handleRotateLeft = () => {
    cropper.value?.rotateLeft()
}
const handleRotateRight = () => {
    cropper.value?.rotateRight()
}
// 上传图片
const handleCaptureUpload = (e: any) => {
    const input = e.target as HTMLInputElement
    if (!/\.(jpg|jpeg|png|JPG|PNG)$/.test(e.target.value)) {
        warningMessage('图片类型要求:jpeg、jpg、png')
        return false
    }
    showCaptureVisible.value = true
    nextTick(() => {
        cropper.value?.selectImg(e)
        input.value = ''
    })
}
// 关闭裁剪
const closeCapture = () => {
    showCaptureVisible.value = false
}
</script>

效果图:

可进行图片旋转,裁剪 自定义裁剪的图片大小

三.vue-cropper的全部参数

 

vue3和ts和vue-cropper 实现图片裁剪预览的更多相关文章

  1. node.js平台下,cropper.js实现图片裁剪预览并转换为base64发送至服务端。

    一 .准备工作 1.首先需要先下载cropper,常规使用npm,进入项目路径后执行以下命令: npm install cropper 2. cropper基于jquery,在此不要忘记引入jq,同时 ...

  2. cropper.js实现图片裁剪预览并转换为base64发送至服务端。

    一 .准备工作 1.首先需要先下载cropper,常规使用npm,进入项目路径后执行以下命令: npm install cropper 2. cropper基于jquery,在此不要忘记引入jq,同时 ...

  3. Java实现图片裁剪预览功能

    在项目中.我们须要做些类似头像上传,图片裁剪的功能,ok看以下文章! 须要插件:jQuery Jcrop 后端代码: package org.csg.upload; import java.awt.R ...

  4. JavaScript实现图片裁剪预览效果~(第一个小玩具)

    感觉开始学习的前一个月真的太不珍惜慕课网的资源了  上面蛮多小玩意真的蛮适合我这样刚入门JavaScript的同学加深使用理解 大概收藏了百来门或大或小的课程  有一个感觉就是学这个真的比光是看书看概 ...

  5. JavaScript实现本地图片上传前进行裁剪预览

    本项目支持IE8+,测试环境IE8,IE9,IE10,IE11,Chrome,FireFox测试通过 另:本项目并不支持Vue,React等,也不建议,引入JQuery和Vue.React本身提倡的开 ...

  6. jQuery Lightbox图片放大预览

    简介:jQuery Lightbox图片放大预览代码是一款可以在用户点击页面中的小图片时,将该图片的高清版本以Lightbox的方式放大显示在页面的中间,提高用户的体验度. 效果展示 http://h ...

  7. js实现FileUpload选择图片后预览功能

    当asp.net的FileUpload选择一个图片后不需要上传就能显示出图片的预览功能, 代码: <%@ Page Language="C#" AutoEventWireup ...

  8. Android 举例说明自己的定义Camera图片和预览,以及前后摄像头切换

    如何调用本地图片,并调用系统拍摄的图像上一博文解释(http://blog.csdn.net/a123demi/article/details/40003695)的功能. 而本博文将通过实例实现自己定 ...

  9. 图片本地预览 flash html5

    dataURI 一种能够在页面嵌入外部资源的URI方案.能够降低图片或者样式表的http请求数量,提高效率. ie8把dataURI 的属性值限制在32k以内. 图片本地预览: 由于安全原因,通过fi ...

  10. 巧用weui.gallery(),点击图片后预览图片

    要在页面需要加载的JS文件: <script src="../js/libs/weui.min.js"></script> 可以去weui的文档中下载,这是 ...

随机推荐

  1. Flink学习(十六) ProcessFunctionAPI(底层API)

    我们之前学习的转换算子是无法访问时间的时间戳信息和水位线信息的.而这些在一些应用场景下,极为重要,例如MapFunction这样的map转换算子就无法访问时间戳或者当前事件的事件时间. 基于此,Dat ...

  2. Log4j2 中三种常见 File 类 Appender 对比与选择

    在 Log4j2 中,若不考虑 Rolling(支持滚动和压缩)类文件 Appender,则包含以下三种文件 Appender:FileAppender.RandomAccessFileAppende ...

  3. Refit 原理解析:从初识到实践

    在现代的分布式系统和微服务架构中,HTTP API 调用是不可或缺的一部分.为了简化 HTTP 请求的构建和解析,我们可以使用 Refit 这个强大的库.Refit 通过将 HTTP API 抽象为接 ...

  4. 【Azure Storage Account】利用App Service作为反向代理, 并使用.NET Storage Account SDK实现上传/下载操作

    问题描述 在使用Azure上的存储服务 Storage Account 的时候,有时需要代替 它原本提供的域名进行访问,比如默认的域名为:mystorageaccount.blob.core.chin ...

  5. C# Socket通信简单示例

    https://files.cnblogs.com/files/mojiejushi/SocketDemo.rar

  6. zookeeper windows 安装

    下载 zookeeper 下载地址为: https://zookeeper.apache.org/releases.html. 选择一个地址点击版本下载: 配置 下载后解压到指定磁盘的 zookeep ...

  7. PIL或Pillow学习2

    接着学习下Pillow常用方法: PIL_test1.py : ''' 9, Pillow图像降噪处理 由于成像设备.传输媒介等因素的影响,图像总会或多或少的存在一些不必要的干扰信息,我们将这些干扰信 ...

  8. windows Oracle 11g安装图解教程

    安装以win7/10 64位系统为例1.将win64_11gR2_database_1of2和win64_11gR2_database_2of2解压到同个文件夹下合并(可以直接左键框住右键点击一起解压 ...

  9. CSAPP学习笔记——chapter8 异常控制流

    CSAPP学习笔记--chapter8 异常控制流 简介 异常控制流(Exceptional Control Flow,ECF)是在计算机系统中处理不寻常或异常情况的一种机制.它允许系统跳出正常的顺序 ...

  10. 【JVM之内存与垃圾回收篇】垃圾回收概述

    垃圾回收概述 概念 这次我们主要关注的是黄色部分,内存的分配与回收 垃圾收集 垃圾收集,不是 Java 语言的伴生产物.早在 1960 年,第一门开始使用内存动态分配和垃圾收集技术的 Lisp 语言诞 ...