​​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. Spark - [03] 资源调度模式

    题记部分 一.Local模式 1.1.概述 Local模式就是运行在一台计算机上的模式,通常就是用于在本机上练手和测试的. 可以通过以下几种方式设置Master (1)local:所欲计算都运行在一个 ...

  2. Linux - centos6忘记root密码怎么办?

    Linux的root密码修改不像Windows的密码修改找回,Windows的登录密码忘记需要介入工具进行解决.CentOS6和CentOS7的密码方法也是不一样的,具体如下 1.开机按esc   2 ...

  3. Visual Studio 好用的主题+字体推荐!!!

    Vs2022主题+字体 Visual Studio(VS)是一款功能强大的集成开发环境(IDE),可以用于开发各种类型的应用程序,包括桌面应用.Web应用.移动应用等.它提供了许多主题设置和字体选项, ...

  4. leetcode两数之和变种(找出所有满足总和的两个数)

    偶尔看到leetcode 的两数之和,但是之前遇到过两数之和的变种,之前一开始想不出来,后面看了别人的题解才想到解法,这里记录一下. 题目描述: 原leetcode题目描述 给定一个整数数组 nums ...

  5. xshell连接Win10下子系统Unbuntu

    自带的ssh server不好用,需要先卸载再安装. 1. 卸载 ssh server sudo apt-get remove openssh-server 2. 安装 ssh server sudo ...

  6. gland go list-m:无法识别的导入路径

    可以使用go代理:https://goproxy.io 或者阿里云的镜像站:https://mirrors.aliyun.com/goproxy/ 重启即可

  7. Unity开发Hololens2—环境配置

    博客地址:https://www.cnblogs.com/zylyehuo/ 配置如下: win11 专业版 Unity2018.4.26f1 / 2019.4.11f1 Hololens2 VS20 ...

  8. Pydantic根校验器:构建跨字段验证系统

    title: Pydantic根校验器:构建跨字段验证系统 date: 2025/3/24 updated: 2025/3/24 author: cmdragon excerpt: Pydantic根 ...

  9. Lambda表达式的省略规则、Lambda和匿名内部类的区别--java进阶day03

    1.省略规则 2.流程讲解 主方法中调用useStringhandler,该方法的形参是接口,所以我们要给实现类对象,这里我们使用匿名内部类 use...方法进栈,形参也是变量,接收到匿名内部类(如下 ...

  10. Windows Server 2012 配置 FTP

    环境 Windows Server 2012 安装步骤 打开服务器管理器 管理 - 添加角色和功能 开始之前 选择安装类型 服务器选择 选择对应的服务器... 服务器角色 功能 确认 安装进度 配置步 ...